diff --git a/.github/generate_change_log.sh b/.github/generate_change_log.sh index 9caf6f2023..b50893ddfa 100755 --- a/.github/generate_change_log.sh +++ b/.github/generate_change_log.sh @@ -24,26 +24,20 @@ TESTNET_ZIP_SUM="$(checksum ./testnet.zip)" LINUX_BIN_SUM="$(checksum ./linux/geth)" MAC_BIN_SUM="$(checksum ./macos/geth)" WINDOWS_BIN_SUM="$(checksum ./windows/geth.exe)" -ARM5_BIN_SUM="$(checksum ./arm5/geth-linux-arm-5)" -ARM6_BIN_SUM="$(checksum ./arm6/geth-linux-arm-6)" -ARM7_BIN_SUM="$(checksum ./arm7/geth-linux-arm-7)" ARM64_BIN_SUM="$(checksum ./arm64/geth-linux-arm64)" OUTPUT=$(cat <<-END ## Changelog\n ${CHANGE_LOG}\n ## Assets\n -| Assets | Sha256 Checksum |\n -| :-----------: |------------|\n -| mainnet.zip | ${MAINNET_ZIP_SUM} |\n -| testnet.zip | ${TESTNET_ZIP_SUM} |\n -| geth_linux | ${LINUX_BIN_SUM} |\n -| geth_mac | ${MAC_BIN_SUM} |\n -| geth_windows | ${WINDOWS_BIN_SUM} |\n -| geth_linux_arm-5 | ${ARM5_BIN_SUM} |\n -| geth_linux_arm-6 | ${ARM6_BIN_SUM} |\n -| geth_linux_arm-7 | ${ARM7_BIN_SUM} |\n +| Assets | Sha256 Checksum | +| :-----------: |------------| +| mainnet.zip | ${MAINNET_ZIP_SUM} | +| testnet.zip | ${TESTNET_ZIP_SUM} | +| geth_linux | ${LINUX_BIN_SUM} | +| geth_mac | ${MAC_BIN_SUM} | +| geth_windows | ${WINDOWS_BIN_SUM} | | geth_linux_arm64 | ${ARM64_BIN_SUM} |\n END ) -echo -e ${OUTPUT} \ No newline at end of file +echo -e "${OUTPUT}" \ No newline at end of file diff --git a/.github/workflows/unit-test.yml b/.github/workflows/unit-test.yml index d692c2f0d8..f4d9e053f2 100644 --- a/.github/workflows/unit-test.yml +++ b/.github/workflows/unit-test.yml @@ -45,6 +45,8 @@ jobs: - name: Unit Test env: + CGO_CFLAGS: "-O -D__BLST_PORTABLE__" + CGO_CFLAGS_ALLOW: "-O -D__BLST_PORTABLE__" ANDROID_HOME: "" # Skip android test run: | go mod download diff --git a/.gitignore b/.gitignore index 0271db9ecd..d98f7c9227 100644 --- a/.gitignore +++ b/.gitignore @@ -50,3 +50,5 @@ profile.cov **/yarn-error.log cmd/geth/node/ cmd/geth/__debug_bin +cmd/bootnode/bootnode +graphql/__debug_bin diff --git a/CHANGELOG.md b/CHANGELOG.md index ee85feb6ef..780fe2e162 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,40 @@ # Changelog +## v1.2.0 +FEATURE +* [\#936](https://github.com/bnb-chain/bsc/pull/936) BEP-126: Introduce Fast Finality Mechanism +* [\#1325](https://github.com/bnb-chain/bsc/pull/1325) genesis: add BEP174 changes to relayer contract +* [\#1357](https://github.com/bnb-chain/bsc/pull/1357) Integration API for EIP-4337 bundler with an L2 validator/sequencer +* [\#1463](https://github.com/bnb-chain/bsc/pull/1463) BEP-221: implement cometBFT light block validation +* [\#1493](https://github.com/bnb-chain/bsc/pull/1493) bep: update the bytecode of luban fork after the contract release + +IMPROVEMENT +* [\#1486](https://github.com/bnb-chain/bsc/pull/1486) feature: remove diff protocol registration +* [\#1434](https://github.com/bnb-chain/bsc/pull/1434) fix: improvements after testing fast finality + +BUGFIX +* [\#1430](https://github.com/bnb-chain/bsc/pull/1430) docker: upgrade alpine version & remove apks version +* [\#1458](https://github.com/bnb-chain/bsc/pull/1458) cmd/faucet: clear reqs list when reorg to lower nonce +* [\#1484](https://github.com/bnb-chain/bsc/pull/1484) fix: a deadlock caused by bsc protocol handeshake timeout + +## v1.1.23 +BUGFIX +* [\#1464](https://github.com/bnb-chain/bsc/pull/1464) fix: panic on using WaitGroup after it is freed + +## v1.1.22 +FEATURE +* [\#1361](https://github.com/bnb-chain/bsc/pull/1361) cmd/faucet: merge ipfaucet2 branch to develop + +IMPROVEMENT +* [\#1412](https://github.com/bnb-chain/bsc/pull/1412) fix: init-network with config.toml without setting TimeFormat +* [\#1401](https://github.com/bnb-chain/bsc/pull/1401) log: support custom time format configuration +* [\#1382](https://github.com/bnb-chain/bsc/pull/1382) consnesus/parlia: abort sealing when block in the same height has updated +* [\#1383](https://github.com/bnb-chain/bsc/pull/1383) miner: no need to broadcast sidechain header mined by this validator + +BUGFIX +* [\#1379](https://github.com/bnb-chain/bsc/pull/1379) UT: fix some flaky tests +* [\#1403](https://github.com/bnb-chain/bsc/pull/1403) Makefile: fix devtools install error +* [\#1381](https://github.com/bnb-chain/bsc/pull/1381) fix: snapshot generation issue after chain reinit from a freezer + ## v1.1.21 FEATURE * [\#1389](https://github.com/bnb-chain/bsc/pull/1389) upgrade: update the fork height of planck upgrade on mainnet @@ -55,7 +91,6 @@ BUGFIX ## v1.1.18 IMPROVEMENT - * [\#1209](https://github.com/bnb-chain/bsc/pull/1209) metrics: add build info into metrics server * [\#1204](https://github.com/bnb-chain/bsc/pull/1204) worker: NewTxsEvent and triePrefetch reuse in mining task * [\#1195](https://github.com/bnb-chain/bsc/pull/1195) hardfork: update Gibbs fork height and system contract code diff --git a/Dockerfile b/Dockerfile index 2fc8527ab6..316cc2896e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,17 +6,21 @@ ARG BUILDNUM="" # Build Geth in a stock Go builder container FROM golang:1.19-alpine as builder -RUN apk add --no-cache make gcc musl-dev linux-headers git bash +RUN apk add --no-cache make cmake gcc musl-dev linux-headers git bash build-base libc-dev # Get dependencies - will also be cached if we won't change go.mod/go.sum COPY go.mod /go-ethereum/ COPY go.sum /go-ethereum/ RUN cd /go-ethereum && go mod download ADD . /go-ethereum + +# For blst +ENV CGO_CFLAGS="-O -D__BLST_PORTABLE__" +ENV CGO_CFLAGS_ALLOW="-O -D__BLST_PORTABLE__" RUN cd /go-ethereum && go run build/ci.go install ./cmd/geth # Pull Geth into a second stage deploy alpine container -FROM alpine:3.16.0 +FROM alpine:3.17 ARG BSC_USER=bsc ARG BSC_USER_UID=1000 @@ -26,9 +30,9 @@ ENV BSC_HOME=/bsc ENV HOME=${BSC_HOME} ENV DATA_DIR=/data -ENV PACKAGES ca-certificates~=20220614-r0 jq~=1.6 \ - bash~=5.1.16-r2 bind-tools~=9.16.37 tini~=0.19.0 \ - grep~=3.7 curl~=7.83.1 sed~=4.8-r0 +ENV PACKAGES ca-certificates jq \ + bash bind-tools tini \ + grep curl sed gcc RUN apk add --no-cache $PACKAGES \ && rm -rf /var/cache/apk/* \ @@ -56,4 +60,4 @@ USER ${BSC_USER_UID}:${BSC_USER_GID} # rpc ws graphql EXPOSE 8545 8546 8547 30303 30303/udp -ENTRYPOINT ["/sbin/tini", "--", "./docker-entrypoint.sh"] +ENTRYPOINT ["/sbin/tini", "--", "./docker-entrypoint.sh"] \ No newline at end of file diff --git a/Dockerfile.alltools b/Dockerfile.alltools index 3205b412e4..c3cfed9130 100644 --- a/Dockerfile.alltools +++ b/Dockerfile.alltools @@ -13,6 +13,9 @@ COPY go.sum /go-ethereum/ RUN cd /go-ethereum && go mod download ADD . /go-ethereum +# For blst +ENV CGO_CFLAGS="-O -D__BLST_PORTABLE__" +ENV CGO_CFLAGS_ALLOW="-O -D__BLST_PORTABLE__" RUN cd /go-ethereum && go run build/ci.go install # Pull all binaries into a second stage deploy alpine container diff --git a/Makefile b/Makefile index b35a4a9e4d..adda257e70 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,6 @@ .PHONY: geth android ios evm all test truffle-test clean .PHONY: docker -.PHONY: geth-linux-arm geth-linux-arm64 geth-linux-arm5 geth-linux-arm6 geth-linux-arm7 GOBIN = ./build/bin GO ?= latest @@ -17,23 +16,6 @@ geth: @echo "Done building." @echo "Run \"$(GOBIN)/geth\" to launch geth." -ldflags = -X main.gitCommit=$(GIT_COMMIT) \ - -X main.gitDate=$(GIT_COMMIT_DATE) - -geth-linux-arm: geth-linux-arm5 geth-linux-arm6 geth-linux-arm7 geth-linux-arm64 - -geth-linux-arm5: - env GO111MODULE=on GOARCH=arm GOARM=5 GOOS=linux go build -ldflags="$(ldflags)" -o build/bin/geth-linux-arm-5 ./cmd/geth - -geth-linux-arm6: - env GO111MODULE=on GOARCH=arm GOARM=6 GOOS=linux go build -ldflags="$(ldflags)" -o build/bin/geth-linux-arm-6 ./cmd/geth - -geth-linux-arm7: - env GO111MODULE=on GOARCH=arm GOARM=7 GOOS=linux go build -ldflags="$(ldflags)" -o build/bin/geth-linux-arm-7 ./cmd/geth - -geth-linux-arm64: - env GO111MODULE=on GOARCH=arm64 GOOS=linux go build -ldflags="$(ldflags)" -o build/bin/geth-linux-arm64 ./cmd/geth - all: $(GORUN) build/ci.go install @@ -74,7 +56,7 @@ clean: devtools: env GOBIN= go install golang.org/x/tools/cmd/stringer@latest - env GOBIN= go install github.com/kevinburke/go-bindata/go-bindata@latest + env GOBIN= go install github.com/kevinburke/go-bindata@latest env GOBIN= go install github.com/fjl/gencodec@latest env GOBIN= go install github.com/golang/protobuf/protoc-gen-go@latest env GOBIN= go install ./cmd/abigen diff --git a/accounts/abi/bind/backend.go b/accounts/abi/bind/backend.go index c16990f395..1a03d13578 100644 --- a/accounts/abi/bind/backend.go +++ b/accounts/abi/bind/backend.go @@ -24,6 +24,7 @@ import ( "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/internal/ethapi" ) var ( @@ -96,6 +97,9 @@ type ContractTransactor interface { // SendTransaction injects the transaction into the pending pool for execution. SendTransaction(ctx context.Context, tx *types.Transaction) error + + // SendTransactionConditional injects the conditional transaction into the pending pool for execution after verification. + SendTransactionConditional(ctx context.Context, tx *types.Transaction, opts ethapi.TransactionOpts) error } // ContractFilterer defines the methods needed to access log events using one-off diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go index f8ceec8838..34f23e8330 100644 --- a/accounts/abi/bind/backends/simulated.go +++ b/accounts/abi/bind/backends/simulated.go @@ -40,6 +40,7 @@ import ( "github.com/ethereum/go-ethereum/eth/filters" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/event" + "github.com/ethereum/go-ethereum/internal/ethapi" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rpc" @@ -677,6 +678,18 @@ func (b *SimulatedBackend) SendTransaction(ctx context.Context, tx *types.Transa return nil } +// SendTransaction updates the pending block to include the given transaction. +func (b *SimulatedBackend) SendTransactionConditional(ctx context.Context, tx *types.Transaction, opts ethapi.TransactionOpts) error { + state, err := b.blockchain.State() + if err != nil { + return err + } + if err := opts.Check(b.pendingBlock.NumberU64(), b.pendingBlock.Time(), state); err != nil { + return err + } + return b.SendTransaction(ctx, tx) +} + // FilterLogs executes a log filter operation, blocking during execution and // returning all the results in one batch. // @@ -826,11 +839,22 @@ type filterBackend struct { func (fb *filterBackend) ChainDb() ethdb.Database { return fb.db } func (fb *filterBackend) EventMux() *event.TypeMux { panic("not supported") } -func (fb *filterBackend) HeaderByNumber(ctx context.Context, block rpc.BlockNumber) (*types.Header, error) { - if block == rpc.LatestBlockNumber { +func (fb *filterBackend) HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error) { + switch number { + case rpc.PendingBlockNumber: + if block := fb.backend.pendingBlock; block != nil { + return block.Header(), nil + } + return nil, nil + case rpc.LatestBlockNumber: return fb.bc.CurrentHeader(), nil + case rpc.FinalizedBlockNumber: + return fb.bc.CurrentFinalBlock(), nil + case rpc.SafeBlockNumber: + return fb.bc.CurrentSafeBlock(), nil + default: + return fb.bc.GetHeaderByNumber(uint64(number.Int64())), nil } - return fb.bc.GetHeaderByNumber(uint64(block.Int64())), nil } func (fb *filterBackend) HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error) { @@ -869,10 +893,18 @@ func (fb *filterBackend) SubscribeNewTxsEvent(ch chan<- core.NewTxsEvent) event. return nullSubscription() } +func (fb *filterBackend) SubscribeNewVoteEvent(ch chan<- core.NewVoteEvent) event.Subscription { + return nullSubscription() +} + func (fb *filterBackend) SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription { return fb.bc.SubscribeChainEvent(ch) } +func (fb *filterBackend) SubscribeFinalizedHeaderEvent(ch chan<- core.FinalizedHeaderEvent) event.Subscription { + return fb.bc.SubscribeFinalizedHeaderEvent(ch) +} + func (fb *filterBackend) SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent) event.Subscription { return fb.bc.SubscribeRemovedLogsEvent(ch) } diff --git a/accounts/abi/bind/base_test.go b/accounts/abi/bind/base_test.go index 08ba18f95e..0fe12cc9c6 100644 --- a/accounts/abi/bind/base_test.go +++ b/accounts/abi/bind/base_test.go @@ -30,6 +30,7 @@ import ( "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/internal/ethapi" "github.com/ethereum/go-ethereum/rlp" "github.com/stretchr/testify/assert" ) @@ -74,6 +75,10 @@ func (mt *mockTransactor) SendTransaction(ctx context.Context, tx *types.Transac return nil } +func (mt *mockTransactor) SendTransactionConditional(ctx context.Context, tx *types.Transaction, opts ethapi.TransactionOpts) error { + return nil +} + type mockCaller struct { codeAtBlockNumber *big.Int callContractBlockNumber *big.Int diff --git a/accounts/abi/bind/bind_test.go b/accounts/abi/bind/bind_test.go index 5e3d0fccfe..051cf97a5c 100644 --- a/accounts/abi/bind/bind_test.go +++ b/accounts/abi/bind/bind_test.go @@ -2114,6 +2114,13 @@ func TestGolangBindings(t *testing.T) { 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", "-compat=1.19") tidier.Dir = pkg if out, err := tidier.CombinedOutput(); err != nil { diff --git a/beacon/engine/types.go b/beacon/engine/types.go new file mode 100644 index 0000000000..ecdf67176c --- /dev/null +++ b/beacon/engine/types.go @@ -0,0 +1,18 @@ +// Copyright 2022 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 . + +// just for prysm compile pass +package engine diff --git a/build/checksums.txt b/build/checksums.txt index 1d2f1cba17..f781ba6b7d 100644 --- a/build/checksums.txt +++ b/build/checksums.txt @@ -14,44 +14,52 @@ e4032e7c52ebc48bad5c58ba8de0759b6091d9b1e59581a8a521c8c9d88dbe93 go1.19.5.linux- 764871cbca841a99a24e239b63c68a4aaff4104658e3165e9ca450cac1fcbea3 go1.19.5.linux-s390x.tar.gz 85a75555e82d8aa6f486d8d29491c593389682acce9f0c270090d5938eee30ef go1.19.5.windows-arm64.zip -06456f980c7dfddfa6a30bf37a839843ee6564a2f9c4c9a8c1319dcdfeae0748 golangci-lint-1.50.1-linux-mips64le.tar.gz -0f615fb8c364f6e4a213f2ed2ff7aa1fc2b208addf29511e89c03534067bbf57 golangci-lint-1.50.1-darwin-amd64.tar.gz -10200bdf2a22d63a3b7f51d3b28e8b919b638b449b6d7867b26af008e33190b6 golangci-lint-1.50.1-linux-ppc64le.deb -131a339395aedd1e32672d9b6243abfeef91adff493bd4fb8d3edcd38e7d7498 golangci-lint-1.50.1-linux-arm64.rpm -162667015519495c2ae35955ff7804d2170ee94a24497cbe0ddf163d5ce10dd4 golangci-lint-1.50.1-linux-ppc64le.tar.gz -193fcf9b72345a8a0d27c330d8433eb6c9bce249bb2e1edea7143d4dbc1acaf4 golangci-lint-1.50.1-linux-mips64le.rpm -1dfeff81f222ec776bee2b8ddf36d727b0300b71e672e80096b2897be296f825 golangci-lint-1.50.1-windows-armv6.zip -26daf55ff7ab4d858058d666ed08ba7c1757d3eb47b24c071955d2bd30fc368a golangci-lint-1.50.1-linux-mips64.deb -3c6ff7318c574cf6096014fd527b36430721cc7a484819a7569478e20a478e1c golangci-lint-1.50.1-freebsd-amd64.tar.gz -3ca9753d7804b34f9165427fbe339dbea69bd80be8a10e3f02c6037393b2e1c4 golangci-lint-1.50.1-darwin-arm64.tar.gz -3ea0a6d5946340f6831646e2c67a317dd9b35bdc4e09b2df953a86f09ba05d74 golangci-lint-1.50.1-linux-arm64.tar.gz -4ba1dc9dbdf05b7bdc6f0e04bdfe6f63aa70576f51817be1b2540bbce017b69a golangci-lint-1.50.1-linux-amd64.tar.gz -4ed8e23077e2466350a100b988cde79750d9ef03498aa4f05d72dbd2e4b28233 golangci-lint-1.50.1-linux-s390x.rpm -50d05c2932a8ea567882fe0586f6b5c1bbfb2a2e944dafaa8f649606ad92105f golangci-lint-1.50.1-linux-ppc64le.rpm -5af2ab7c6d389dde240f7f0d661742cfce615b4b8f8f879c7c36b398f7000db1 golangci-lint-1.50.1-linux-s390x.deb -656ea0215985dfd02ed14018cee868f518d34e2274b14ec675b01aea0d305e28 golangci-lint-1.50.1-freebsd-386.tar.gz -6c371d9a37cad2d3719c45d113a07c9619e52406ca2381d247c217a41c6f5d57 golangci-lint-1.50.1-linux-armv7.deb -6d11fb6ed91ba3aecbf2ea8e1a95dce16cf0449d54aa77c607ac4e75cc43213a golangci-lint-1.50.1-windows-386.zip -73ad2af342e00e59f0a5fbd71cfb17c5dc0f765d2cf4391d5a69c79a7a8b24af golangci-lint-1.50.1-linux-mips64.rpm -757d4f17177c6eff01974e2c8e3122b85d542d1a375c416d2a870ef785ad188b golangci-lint-1.50.1-linux-arm64.deb -7fd52d1da270fa8448c975d2500b6ef2d19db143b6cfc205de16612d6f4effa9 golangci-lint-1.50.1-windows-arm64.zip -81f3136bc111bfe51da293fafcee7642dbf998e2d25bf83d24a2ff18f8d1fc14 golangci-lint-1.50.1-linux-armv7.tar.gz -8965c4327e742444bd4359bd952d42ebc645eba929d3826dd12adb8a14cc6248 golangci-lint-1.50.1-linux-386.tar.gz -8c2da214884db02fb7f3d929672c515ae3b9d10defad4dd661c4ab365a316d68 golangci-lint-1.50.1-windows-amd64.zip -96ae5ef97fec1487bcfd298e9341855ed6bf2f7d6a0bd9dfa758d2c1e4da96ec golangci-lint-1.50.1-linux-mips64.tar.gz -96ce5d9e7ae8134342e8c671ca357d92096b76673b61caf5524bfd6d772ee714 golangci-lint-1.50.1-linux-riscv64.deb -980832f12fbdd0a8e636666839b168c2bbf0ca573ff50b042d3977f65c4987d7 golangci-lint-1.50.1-linux-armv6.tar.gz -999126cbd30f08b41b9eb3cef0bb72686eace82d9cb388e8e24a910ff7a8be51 golangci-lint-1.50.1-linux-386.rpm -a2f2da85622630ff2d0aecac1acc1b3b62c4853594e49fc5a266d6ddbe1a692e golangci-lint-1.50.1-freebsd-armv7.tar.gz -a8af864c92743243ae986f20afdcc58b2cb15b0063e2821c519dcc3c8efc669d golangci-lint-1.50.1-linux-386.deb -aaa3e42de0a57c7c1f64991e3c6d0f9a97aa06455a1cde5a55c59a7fa76e2045 golangci-lint-1.50.1-linux-riscv64.tar.gz -bcdcd7a8068aa91bba432a20909babc911269504325aeff15171f29ecc72b9f0 golangci-lint-1.50.1-linux-mips64le.deb -c1d3abf0d873c7e1f123bf468f940b152526aa5af72aa5f1f5acc1733012293c golangci-lint-1.50.1-linux-armv7.rpm -c2955d6b10ce005ee20b4ad03e5cd805076971a5335a215a757d1ab72db499f9 golangci-lint-1.50.1-linux-amd64.deb -c79ec2884ff743dd965bace09f4f22d5412ccfc3fbd4aec719c8edc48fb455a0 golangci-lint-1.50.1-linux-s390x.tar.gz -c946f6ecb87ddc4f32a98baad0aa9b59f3066b04b2dc822d085c184f85764c7b golangci-lint-1.50.1-windows-armv7.zip -c9c4856e01166e835888c82af02c3952a3b55b75d5c02b674501c03f5ea1e107 golangci-lint-1.50.1-linux-amd64.rpm -dfe91654cbc5c12245c608b0fad44772ce90938c483ff945a0059442f5f3722f golangci-lint-1.50.1-freebsd-armv6.tar.gz -e140169da4ec3d1132277f2109d7202638a6032326bdeada547ffcd9d8cbedbc golangci-lint-1.50.1-linux-armv6.rpm -ecbbc8c35787aea093ef5c639972612a2300bbdc75b21466f4674f8c0d2e38ed golangci-lint-1.50.1-linux-armv6.deb -f42db20276811d7e6002d237985e658a0d1bca36586642bc071e9df9454fb4fc golangci-lint-1.50.1-linux-riscv64.rpm +000d4d58f1e25323aaf0da20b337d059d401c8c1fb31cef92ce50ef35c05e877 golangci-lint-1.52.2-linux-ppc64le.deb +0970b2e3ecc20003a0fc78b078623ab27c61f0f809a44288e2cc438bfbbf5616 golangci-lint-1.52.2-linux-s390x.deb +0bfe9b51f68a33cc4e43139151d8032b57b15e61a19f5a7554b687a3fa166ab8 golangci-lint-1.52.2-netbsd-armv7.tar.gz +0e4e24085d364f4e03752c060d5f37b5ead52acd62f07392f4c9022515e0ecd8 golangci-lint-1.52.2-linux-armv7.rpm +0f19ad6c037d45867f4978287a7a6d78bc761daf8e6cb3a5e6af86d5714b0258 golangci-lint-1.52.2-linux-armv6.tar.gz +1506b19f3f0410f6d85d1e339a47fcc84646d552516c0f429dc8cd7f34b4069a golangci-lint-1.52.2-windows-armv6.zip +1cc68baa226e186c15c5514a6e93b1cc8d47ff06aaf1a395b8266434cb01df29 golangci-lint-1.52.2-linux-386.rpm +1d23661087ae686563e40d3b1e33f309dd3b4ba7d1c7e571ca7723f77a52a9e4 golangci-lint-1.52.2-linux-s390x.rpm +227673a18d21b428f1768bb8ee46e38c36a0f002960bc6211ef6137b85d03f52 golangci-lint-1.52.2-freebsd-armv7.tar.gz +24f0272e5741c05c59e7162b7ff0258cfa6beb0d9265bd87c386fe80ac25135d golangci-lint-1.52.2-linux-mips64.deb +3abc8ad30b336ccbe3c5e3c65fa146f5b12d8e81e644345fa8d51cdbaa8cb570 golangci-lint-1.52.2-netbsd-amd64.tar.gz +40a2645b4c7bd94c16618eb0f12b32cd54c17e5620f761cf477b256d3622f299 golangci-lint-1.52.2-windows-386.zip +40b40002e07db81628d94108265525052c58fc9ce358bef26a36d27f0aea3d87 golangci-lint-1.52.2-windows-amd64.zip +41e936b62ba4fc66c02daf6fa9cf74213bc2220745c7a796acbe197c05ed26bb golangci-lint-1.52.2-netbsd-armv6.tar.gz +4bcbb4cf34bf3c8ae1ca880d12516a999499189326621599f8362ededd6e4229 golangci-lint-1.52.2-linux-riscv64.tar.gz +4edb83f1433f7c57f06f79a7fc30bf3f920c1f86c334e481661ac6627d80293f golangci-lint-1.52.2-linux-arm64.deb +50d662e86d094dbad6634d086eca4f670ffa8ea7142508d8da357a2d750ac21a golangci-lint-1.52.2-linux-armv7.tar.gz +6891597bedbcd7e530d08ed198bab7eeb9b23f3f8161dc6e87505b783cb11593 golangci-lint-1.52.2-windows-arm64.zip +6d79f4f3448b70e83952e746fcb9e251c6ba94ec2790a912806cc1704ade4d64 golangci-lint-1.52.2-linux-mips64.rpm +6de51ae05d39002421caf6049e0dd0014a2f10961471c5547c905d33d8e6adf1 golangci-lint-1.52.2-linux-armv6.deb +715dc0f0cf3538c3b2c75f084dde8dcdc3485b3494f42a6d0d9c0dc61e62b5a8 golangci-lint-1.52.2-linux-s390x.tar.gz +7c559332a97ee49b80427aba5a7122e17cac18c57e700f48e6db5ffcbbb61b2b golangci-lint-1.52.2-linux-arm64.rpm +81201bb5f19897fefb4380af2e187a0133dc5efda22254698c063cc36a601f43 golangci-lint-1.52.2-linux-386.deb +89e523d45883903cfc472ab65621073f850abd4ffbb7720bbdd7ba66ee490bc8 golangci-lint-1.52.2-darwin-arm64.tar.gz +8d60d63eee38f8de679e57b1a781de32987152f004f852f20cd47baa4c582209 golangci-lint-1.52.2-linux-mips64le.rpm +9e22df0516cbd847910f353d92245e58eab2b6edacc669646bfa06eb032a65a3 golangci-lint-1.52.2-linux-riscv64.deb +a1a74747a196d4ccd2394ea8a461508eb2edf1eb5a88010611debf572991961d golangci-lint-1.52.2-linux-loong64.tar.gz +a7f076d0fb50e0f5bc24d0f3b2567f2cfe864441e6ad20323189b7fde7cc065d golangci-lint-1.52.2-freebsd-386.tar.gz +abc100851a59cbcea2a7e9ff5ad2974a43270135520aeac9a302ca6c712a41e1 golangci-lint-1.52.2-linux-loong64.rpm +adf11a1f7f43b5a431c19cccea260e6205e2e2b42a2d2d450e31c287fec199f2 golangci-lint-1.52.2-linux-amd64.rpm +b2249e43e1624486398f41700dbe4094a4222bf50b2b1b3a740323adb9a1b66f golangci-lint-1.52.2-linux-386.tar.gz +b8e81bf979dc8bf226cb592eb78c1792f1018c3dea1bbeb11517efc4cc3301bb golangci-lint-1.52.2-windows-armv7.zip +bb9a6a0aabe39fb3d581cc200c639ce6598821a53b4d16ec59366c65f4cc2960 golangci-lint-1.52.2-source.tar.gz +c152280b2e61c202614c1c476cf4458922cda0d2781e4492be2c22d45655cae0 golangci-lint-1.52.2-freebsd-armv6.tar.gz +c8bf25c0bca142638ce4bfc921bf23d23038818d57658d69aa4a9947d514d48f golangci-lint-1.52.2-linux-ppc64le.rpm +c9cf72d12058a131746edd409ed94ccd578fbd178899d1ed41ceae3ce5f54501 golangci-lint-1.52.2-linux-amd64.tar.gz +d03f2b331b5139eddea5db2b49066d10a90094747b08d72d7b2d61cf91c79a27 golangci-lint-1.52.2-linux-mips64le.tar.gz +d609c1d49591d714148e1f8c8b5ae9f9565c601aeabc44a5a53ba44b0eb99f36 golangci-lint-1.52.2-linux-riscv64.rpm +d679adad29603ed7549372b64077cccad784e404deffe5c1e9495a06659cff33 golangci-lint-1.52.2-linux-mips64.tar.gz +d91e8cb60920cf0e46958ed917fcdd059738c00d162189c2e878424ffc8ada75 golangci-lint-1.52.2-linux-ppc64le.tar.gz +d9b5820b491e317fb1360775441d68bd3dc2f303439da5b6d536df23977e28c9 golangci-lint-1.52.2-freebsd-amd64.tar.gz +ddeae781cf07c016898efd80eaed6853a91bfaf1f22c08fbbf5cf08a573b98c4 golangci-lint-1.52.2-linux-loong64.deb +dfc5e755cfa95381f61f736780ff736a5b6c9cbccc88140348986c166d484f85 golangci-lint-1.52.2-linux-amd64.deb +e57f2599de73c4da1d36d5255b9baec63f448b3d7fb726ebd3cd64dabbd3ee4a golangci-lint-1.52.2-darwin-amd64.tar.gz +ebfb5b643ba73ef6007236b90f863ae49fc34fd366682c971b7d1308ab28f642 golangci-lint-1.52.2-netbsd-386.tar.gz +f46b60a90fab5916a7de899ad9a3a4b3d77278c2e1737d070719d3ea27919557 golangci-lint-1.52.2-linux-armv7.deb +f6e39d0ac4691c2b9f49d6d5819594f48bb03e18692fd6d100e7114077f710e6 golangci-lint-1.52.2-linux-armv6.rpm +fa5da589075143628a49a0c123ccd76a8717bb6308fb3bdb6bf1df59435d921b golangci-lint-1.52.2-linux-mips64le.deb +fc09a97f8888809fab83a316f7da70c8ed74d4863b7eed7d872cec41911a55e8 golangci-lint-1.52.2-linux-arm64.tar.gz diff --git a/build/ci.go b/build/ci.go index d036b7d6eb..8ab3c0b966 100644 --- a/build/ci.go +++ b/build/ci.go @@ -24,19 +24,18 @@ Usage: go run build/ci.go Available commands are: - install [ -arch architecture ] [ -cc compiler ] [ packages... ] -- builds packages and executables - test [ -coverage ] [ packages... ] -- runs the tests - lint -- runs certain pre-selected linters - archive [ -arch architecture ] [ -type zip|tar ] [ -signer key-envvar ] [ -signify key-envvar ] [ -upload dest ] -- archives build artifacts - importkeys -- imports signing keys from env - debsrc [ -signer key-id ] [ -upload dest ] -- creates a debian source package - nsis -- creates a Windows NSIS installer - aar [ -local ] [ -sign key-id ] [-deploy repo] [ -upload dest ] -- creates an Android archive - xcode [ -local ] [ -sign key-id ] [-deploy repo] [ -upload dest ] -- creates an iOS XCode framework - purge [ -store blobstore ] [ -days threshold ] -- purges old archives from the blobstore + install [ -arch architecture ] [ -cc compiler ] [ packages... ] -- builds packages and executables + test [ -coverage ] [ packages... ] -- runs the tests + lint -- runs certain pre-selected linters + archive [ -arch architecture ] [ -type zip|tar ] [ -signer key-envvar ] [ -signify key-envvar ] [ -upload dest ] -- archives build artifacts + importkeys -- imports signing keys from env + debsrc [ -signer key-id ] [ -upload dest ] -- creates a debian source package + nsis -- creates a Windows NSIS installer + aar [ -local ] [ -sign key-id ] [-deploy repo] [ -upload dest ] -- creates an Android archive + xcode [ -local ] [ -sign key-id ] [-deploy repo] [ -upload dest ] -- creates an iOS XCode framework + purge [ -store blobstore ] [ -days threshold ] -- purges old archives from the blobstore For all commands, -n prevents execution of external programs (dry run mode). - */ package main @@ -198,9 +197,10 @@ func main() { func doInstall(cmdline []string) { var ( - dlgo = flag.Bool("dlgo", false, "Download Go and build with it") - arch = flag.String("arch", "", "Architecture to cross build for") - cc = flag.String("cc", "", "C compiler to cross build with") + dlgo = flag.Bool("dlgo", false, "Download Go and build with it") + arch = flag.String("arch", "", "Architecture to cross build for") + cc = flag.String("cc", "", "C compiler to cross build with") + output = flag.String("o", "", "Output directory for build artifacts") ) flag.CommandLine.Parse(cmdline) @@ -213,7 +213,8 @@ func doInstall(cmdline []string) { // Configure the build. env := build.Env() - gobuild := tc.Go("build", buildFlags(env)...) + buildArgs := buildFlags(env) + gobuild := tc.Go("build", buildArgs...) // arm64 CI builders are memory-constrained and can't handle concurrent builds, // better disable it. This check isn't the best, it should probably @@ -239,7 +240,11 @@ func doInstall(cmdline []string) { for _, pkg := range packages { args := make([]string, len(gobuild.Args)) copy(args, gobuild.Args) - args = append(args, "-o", executablePath(path.Base(pkg))) + outputPath := executablePath(path.Base(pkg)) + if output != nil && *output != "" { + outputPath = *output + } + args = append(args, "-o", outputPath) args = append(args, pkg) build.MustRun(&exec.Cmd{Path: gobuild.Path, Args: args, Env: gobuild.Env}) } @@ -338,7 +343,7 @@ func doLint(cmdline []string) { // downloadLinter downloads and unpacks golangci-lint. func downloadLinter(cachedir string) string { - const version = "1.50.1" + const version = "1.52.2" csdb := build.MustLoadChecksums("build/checksums.txt") arch := runtime.GOARCH diff --git a/cmd/faucet/faucet.go b/cmd/faucet/faucet.go index 639be86159..7c6eb1d781 100644 --- a/cmd/faucet/faucet.go +++ b/cmd/faucet/faucet.go @@ -90,9 +90,6 @@ var ( fixGasPrice = flag.Int64("faucet.fixedprice", 0, "Will use fixed gas price if specified") twitterTokenFlag = flag.String("twitter.token", "", "Bearer token to authenticate with the v2 Twitter API") twitterTokenV1Flag = flag.String("twitter.token.v1", "", "Bearer token to authenticate with the v1.1 Twitter API") - - goerliFlag = flag.Bool("goerli", false, "Initializes the faucet with Görli network config") - rinkebyFlag = flag.Bool("rinkeby", false, "Initializes the faucet with Rinkeby network config") ) var ( @@ -115,7 +112,7 @@ func main() { for i := 0; i < *tiersFlag; i++ { // Calculate the amount for the next tier and format it amount := float64(*payoutFlag) * math.Pow(2.5, float64(i)) - amounts[i] = fmt.Sprintf("%s BNBs", strconv.FormatFloat(amount, 'f', -1, 64)) + amounts[i] = fmt.Sprintf("0.%s BNBs", strconv.FormatFloat(amount, 'f', -1, 64)) if amount == 1 { amounts[i] = strings.TrimSuffix(amounts[i], "s") } @@ -170,9 +167,13 @@ func main() { log.Crit("Failed to render the faucet template", "err", err) } // Load and parse the genesis block requested by the user - genesis, err := getGenesis(genesisFlag, *goerliFlag, *rinkebyFlag) + blob, err := ioutil.ReadFile(*genesisFlag) if err != nil { - log.Crit("Failed to parse genesis config", "err", err) + log.Crit("Failed to read genesis block contents", "genesis", *genesisFlag, "err", err) + } + genesis := new(core.Genesis) + if err = json.Unmarshal(blob, genesis); err != nil { + log.Crit("Failed to parse genesis block json", "err", err) } // Convert the bootnodes to internal enode representations var enodes []*enode.Node @@ -184,13 +185,13 @@ func main() { } } // Load up the account key and decrypt its password - blob, err := ioutil.ReadFile(*accPassFlag) + blob, err = ioutil.ReadFile(*accPassFlag) if err != nil { log.Crit("Failed to read account password contents", "file", *accPassFlag, "err", err) } pass := strings.TrimSuffix(string(blob), "\n") - ks := keystore.NewKeyStore(filepath.Join(os.Getenv("HOME"), ".faucet", "keys"), keystore.StandardScryptN, keystore.StandardScryptP) + ks := keystore.NewKeyStore(filepath.Join(os.Getenv("HOME"), ".faucet", "keys_2"), keystore.StandardScryptN, keystore.StandardScryptP) if blob, err = ioutil.ReadFile(*accJSONFlag); err != nil { log.Crit("Failed to read account key contents", "file", *accJSONFlag, "err", err) } @@ -364,6 +365,11 @@ func (f *faucet) apiHandler(w http.ResponseWriter, r *http.Request) { // Start tracking the connection and drop at the end defer conn.Close() + ipsStr := r.Header.Get("X-Forwarded-For") + ips := strings.Split(ipsStr, ",") + if len(ips) < 2 { + return + } f.lock.Lock() wsconn := &wsConn{conn: conn} @@ -460,7 +466,7 @@ func (f *faucet) apiHandler(w http.ResponseWriter, r *http.Request) { form.Add("secret", *captchaSecret) form.Add("response", msg.Captcha) - res, err := http.PostForm("https://www.google.com/recaptcha/api/siteverify", form) + res, err := http.PostForm("https://hcaptcha.com/siteverify", form) if err != nil { if err = sendError(wsconn, err); err != nil { log.Warn("Failed to send captcha post error to client", "err", err) @@ -499,6 +505,19 @@ func (f *faucet) apiHandler(w http.ResponseWriter, r *http.Request) { address common.Address ) switch { + case strings.HasPrefix(msg.URL, "https://gist.github.com/"): + if err = sendError(wsconn, errors.New("GitHub authentication discontinued at the official request of GitHub")); err != nil { + log.Warn("Failed to send GitHub deprecation to client", "err", err) + return + } + continue + case strings.HasPrefix(msg.URL, "https://plus.google.com/"): + //lint:ignore ST1005 Google is a company name and should be capitalized. + if err = sendError(wsconn, errors.New("Google+ authentication discontinued as the service was sunset")); err != nil { + log.Warn("Failed to send Google+ deprecation to client", "err", err) + return + } + continue case strings.HasPrefix(msg.URL, "https://twitter.com/"): id, username, avatar, address, err = authTwitter(msg.URL, *twitterTokenV1Flag, *twitterTokenFlag) case strings.HasPrefix(msg.URL, "https://www.facebook.com/"): @@ -526,11 +545,20 @@ func (f *faucet) apiHandler(w http.ResponseWriter, r *http.Request) { fund bool timeout time.Time ) + + if ipTimeout := f.timeouts[ips[len(ips)-2]]; time.Now().Before(ipTimeout) { + if err = sendError(wsconn, fmt.Errorf("%s left until next allowance", common.PrettyDuration(time.Until(ipTimeout)))); err != nil { // nolint: gosimple + log.Warn("Failed to send funding error to client", "err", err) + } + f.lock.Unlock() + continue + } + if timeout = f.timeouts[id]; time.Now().After(timeout) { var tx *types.Transaction if msg.Symbol == "BNB" { // User wasn't funded recently, create the funding transaction - amount := new(big.Int).Mul(big.NewInt(int64(*payoutFlag)), ether) + amount := new(big.Int).Div(new(big.Int).Mul(big.NewInt(int64(*payoutFlag)), ether), big.NewInt(10)) amount = new(big.Int).Mul(amount, new(big.Int).Exp(big.NewInt(5), big.NewInt(int64(msg.Tier)), nil)) amount = new(big.Int).Div(amount, new(big.Int).Exp(big.NewInt(2), big.NewInt(int64(msg.Tier)), nil)) @@ -578,6 +606,7 @@ func (f *faucet) apiHandler(w http.ResponseWriter, r *http.Request) { grace := timeout / 288 // 24h timeout => 5m grace f.timeouts[id] = time.Now().Add(timeout - grace) + f.timeouts[ips[len(ips)-2]] = time.Now().Add(timeout - grace) fund = true } f.lock.Unlock() @@ -638,6 +667,9 @@ func (f *faucet) refresh(head *types.Header) error { f.lock.Lock() f.head, f.balance = head, balance f.price, f.nonce = price, nonce + if len(f.reqs) > 0 && f.reqs[0].Tx.Nonce() > f.nonce { + f.reqs = f.reqs[:0] + } for len(f.reqs) > 0 && f.reqs[0].Tx.Nonce() < f.nonce { f.reqs = f.reqs[1:] } @@ -799,7 +831,7 @@ func authTwitter(url string, tokenV1, tokenV2 string) (string, string, string, c address := common.HexToAddress(string(regexp.MustCompile("0x[0-9a-fA-F]{40}").Find(body))) if address == (common.Address{}) { //lint:ignore ST1005 This error is to be displayed in the browser - return "", "", "", common.Address{}, errors.New("No Binance Smart Chain address found to fund") + return "", "", "", common.Address{}, errors.New("No BNB Smart Chain address found to fund") } var avatar string if parts = regexp.MustCompile(`src="([^"]+twimg\.com/profile_images[^"]+)"`).FindStringSubmatch(string(body)); len(parts) == 2 { @@ -925,7 +957,7 @@ func authFacebook(url string) (string, string, common.Address, error) { address := common.HexToAddress(string(regexp.MustCompile("0x[0-9a-fA-F]{40}").Find(body))) if address == (common.Address{}) { //lint:ignore ST1005 This error is to be displayed in the browser - return "", "", common.Address{}, errors.New("No Binance Smart Chain address found to fund") + return "", "", common.Address{}, errors.New("No BNB Smart Chain address found to fund") } var avatar string if parts = regexp.MustCompile(`src="([^"]+fbcdn\.net[^"]+)"`).FindStringSubmatch(string(body)); len(parts) == 2 { @@ -941,19 +973,7 @@ func authNoAuth(url string) (string, string, common.Address, error) { address := common.HexToAddress(regexp.MustCompile("0x[0-9a-fA-F]{40}").FindString(url)) if address == (common.Address{}) { //lint:ignore ST1005 This error is to be displayed in the browser - return "", "", common.Address{}, errors.New("No Binance Smart Chain address found to fund") + return "", "", common.Address{}, errors.New("No BNB Smart Chain address found to fund") } return address.Hex() + "@noauth", "", address, nil } - -// getGenesis returns a genesis based on input args -func getGenesis(genesisFlag *string, goerliFlag bool, rinkebyFlag bool) (*core.Genesis, error) { - switch { - case genesisFlag != nil: - var genesis core.Genesis - err := common.LoadJSON(*genesisFlag, &genesis) - return &genesis, err - default: - return nil, fmt.Errorf("no genesis flag provided") - } -} diff --git a/cmd/faucet/faucet.html b/cmd/faucet/faucet.html index 849145a60d..4f299857ca 100644 --- a/cmd/faucet/faucet.html +++ b/cmd/faucet/faucet.html @@ -1,220 +1,249 @@ - - - - - - {{.Network}}: Faucet - - - - - - - - - - - - - -
-
-
-
-

{{.Network}} Faucet

-
-
-
-
-
- - + + + + + + {{.Network}}: Faucet + + + + + + + + + + + + + +
+ +
+
+
+
+

{{.Network}} Faucet

+
+
+
+
+
+ + -
{{if .Recaptcha}} -
{{end}} -
-
-
-
-
-
-
+
- +
+
+
+
+
+
+ +
+
+
+
+
+

How does this work?

+

BTC,ETH,XRP,BUSD,USDT,USDC,DAI are issued as BEP20 token.

+

Click to get detail about BEP20.

+ +

Support Discord: discord.gg/bnbchain

+ {{if .Recaptcha}}The faucet is running reCaptcha protection against bots.{{end}}
-
-
- -{{if .Recaptcha}} -{{end}} - + // Start a UI updater to push the progress bars forward until they are done + setInterval(function() { + $('.progress-bar').each(function() { + var progress = Number($(this).attr('aria-valuenow')) + 1; + if (progress < 30) { + $(this).attr('aria-valuenow', progress); + $(this).css('width', (progress * 100 / 30) + '%'); + } else if (progress == 30) { + $(this).css('width', '100%'); + $(this).addClass("progress-bar-danger"); + } + }) + $('.timer').each(function() { + var index = Number($(this).attr('id').substring(5)); + $(this).html(moment.duration(moment(requests[index].time).unix()-moment().unix(), 'seconds').humanize(true)); + }) + }, 1000); + + // Establish a websocket connection to the API server + reconnect(); + {{if .Recaptcha}} + {{end}} + diff --git a/cmd/faucet/website.go b/cmd/faucet/website.go index 854f4404d9..dae64a7f23 100644 --- a/cmd/faucet/website.go +++ b/cmd/faucet/website.go @@ -1,6 +1,6 @@ // Code generated by go-bindata. DO NOT EDIT. // sources: -// faucet.html (8.959kB) +// faucet.html (10.721kB) package main @@ -10,7 +10,6 @@ import ( "crypto/sha256" "fmt" "io" - "io/ioutil" "os" "path/filepath" "strings" @@ -69,7 +68,7 @@ func (fi bindataFileInfo) Sys() interface{} { return nil } -var _faucetHtml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xd4\x5a\x5b\x8f\xe3\x36\xb2\x7e\x76\xff\x8a\x8a\xce\x24\x96\x4f\xb7\x24\x7b\x3a\x37\xd8\x92\x0f\xa6\x27\x39\xc1\x2c\x76\x27\x41\x26\xc1\xee\x22\xc9\x03\x2d\x95\x2d\x4e\x53\xa4\x42\x96\xec\x76\x0c\xff\xf7\x05\xa9\x8b\xe5\x4b\xf7\xce\x25\xc0\x62\xe7\xc1\x2d\x92\xc5\xaa\x8f\x55\xc5\xba\x48\x13\x7f\xf2\xcd\xf7\x2f\x7f\xfa\xe7\x0f\xdf\x42\x4e\x85\x98\x5f\xc5\xf6\x0f\x08\x26\x57\x89\x87\xd2\xb3\x13\xc8\xb2\xf9\xd5\x20\x2e\x90\x18\xa4\x39\xd3\x06\x29\xf1\x2a\x5a\x06\x5f\x7b\xdd\x7c\x4e\x54\x06\xf8\x7b\xc5\xd7\x89\xf7\x8f\xe0\xe7\x17\xc1\x4b\x55\x94\x8c\xf8\x42\xa0\x07\xa9\x92\x84\x92\x12\xef\xd5\xb7\x09\x66\x2b\x3c\x6c\x93\xac\xc0\xc4\x5b\x73\xdc\x94\x4a\x53\x8f\x72\xc3\x33\xca\x93\x0c\xd7\x3c\xc5\xc0\x0d\x6e\x80\x4b\x4e\x9c\x89\xc0\xa4\x4c\x60\x32\xf1\xe6\x57\x57\x83\x98\x38\x09\x9c\xef\x76\xe1\x6b\xa4\x8d\xd2\xf7\xfb\xfd\x14\xfe\x9f\x55\x29\x52\x1c\xd5\x6b\x96\x4a\x70\x79\x0f\xb9\xc6\x65\xe2\x59\xa4\x66\x1a\x45\x69\x26\xdf\x9a\x30\x15\xaa\xca\x96\x82\x69\x0c\x53\x55\x44\xec\x2d\x7b\x88\x04\x5f\x98\x88\x36\x9c\x08\x75\xb0\x50\x8a\x0c\x69\x56\x46\xb7\xe1\x6d\xf8\x55\x94\x1a\x13\x75\x73\x61\xc1\x65\x98\x1a\xe3\x81\x46\x91\x78\x86\xb6\x02\x4d\x8e\x48\x1e\x44\xf3\x0f\x12\xbb\x54\x92\x02\xb6\x41\xa3\x0a\x8c\x3e\x0f\xbf\x0a\xc7\x4e\x62\x7f\xfa\x69\xa1\x57\x83\xd8\xa4\x9a\x97\x04\x46\xa7\xef\x2c\xf6\xed\xef\x15\xea\x6d\x74\x1b\x4e\xc2\x49\x33\x70\x62\xde\x1a\x6f\x1e\x47\x35\xc3\xf9\xc7\xb0\x0e\xa4\xa2\x6d\xf4\x3c\xfc\x3c\x9c\x44\x25\x4b\xef\xd9\x0a\xb3\x56\x90\x5d\x0a\xdb\xc9\x3f\x4b\xec\x63\xf6\x7b\x7b\x6a\xbe\x3f\x41\x56\xa1\x0a\x94\x14\xbe\x35\xd1\xf3\x70\xf2\x75\x38\x6e\x27\xce\xd9\x5b\xfe\xd6\x5e\xf3\xab\xc1\x20\x5c\xa3\x26\x9e\x32\x11\xa4\x28\x09\x35\xec\xae\x06\x83\x41\xc1\x65\x90\x23\x5f\xe5\x34\x85\xc9\x78\xfc\xe9\xec\xc2\xe4\x3a\x77\xb3\x19\x37\xa5\x60\xdb\x29\x2c\x05\x3e\xb8\x19\x26\xf8\x4a\x06\x9c\xb0\x30\x53\xa8\xb9\xda\xf9\xbd\x95\x56\x6a\xb5\xd2\x68\x4c\x2d\xa6\x54\x86\x13\x57\x72\x6a\x9d\x88\x11\x5f\xe3\x39\xa1\x29\x99\x3c\xa5\x66\x0b\xa3\x44\x45\x78\x0c\x60\x21\x54\x7a\xef\xa6\xdc\x55\xed\x21\x4f\x95\x50\x7a\x0a\x9b\x9c\x53\x27\xa1\xd4\xd8\xb0\x65\x59\xc6\xe5\x6a\x0a\x5f\x96\x35\xfe\x82\xe9\x15\x97\x53\x18\x37\xa4\x71\xd4\x68\x2b\x8e\xea\x28\x74\x15\x2f\x54\xb6\x9d\x5f\xc5\x19\x5f\x43\x2a\x98\x31\x89\x77\xa2\x46\x17\x5c\x7a\xcb\x36\xa4\x30\x2e\xeb\x85\xa3\x15\xad\x36\x1e\x38\x01\x89\x57\x4b\x0e\x16\x8a\x48\x15\x53\x98\x58\x44\x6e\xc3\x09\x2f\x11\x88\x55\x30\x79\x5e\x2f\x0d\xe2\x7c\xd2\x32\x20\x7c\xa0\xc0\xe9\xbf\xd3\xbc\x37\x8f\x79\xbb\x73\xc9\x60\xc9\x82\x05\xa3\xdc\x03\xa6\x39\x0b\x72\x9e\x65\x28\x13\x8f\x74\x85\xd6\x43\xf8\x1c\xfa\x41\xac\x8b\x61\xf9\xa4\x46\x11\x65\x7c\xed\x0e\xd0\x3d\x9c\x9c\xe4\x31\xb0\x5f\x43\xf3\xa0\x96\x4b\x83\x14\x74\xd8\x7b\xa4\x5c\x96\x15\x05\x2b\xad\xaa\xb2\x59\x1d\xc4\x6e\x0e\x78\x96\x78\x95\x16\x5e\x13\xa9\xdd\x23\x6d\xcb\xe6\xc0\x5e\x77\x3c\xa5\x8b\xc0\x6a\x5a\x2b\xe1\x41\x29\x58\x8a\xb9\x12\x19\xea\xc4\x7b\xa3\x52\xce\x04\xc8\xfa\x64\xf0\xf3\x8f\x7f\x85\xc6\x24\x5c\xae\x60\xab\x2a\x0d\x77\x5c\x32\x99\x22\xbc\x29\x98\x26\x78\x99\x33\x2e\x81\x65\x99\x75\xc2\x30\x0c\x3b\x44\xce\x1f\xcf\x11\x07\x0b\x92\x2d\x8d\x25\x5b\x54\x44\xaa\x23\x5c\x90\x84\x05\xc9\x20\xc3\x25\xab\x04\x41\xa6\x55\x99\xa9\x8d\x0c\x48\xad\x56\x36\x39\xd5\xa7\xa9\x37\x79\x90\x31\x62\xcd\x52\xe2\xb5\xb4\xad\xc9\x98\x29\x55\x59\x95\x8d\xd1\xea\x49\x7c\x28\x99\xcc\x30\xb3\x26\x16\x06\xbd\xf9\x77\x7c\x8d\x50\x20\xdc\xbd\xbe\x1b\x9c\xda\x3f\x65\x1a\x29\xe8\xb3\x3c\xf3\x82\x38\xaa\xa1\xd4\x07\x82\xe6\x5f\x5c\x89\x96\x53\x77\x80\x02\x65\x05\x47\xa3\x40\xdb\x10\xe1\xcd\x77\x3b\xcd\xe4\x0a\xe1\x19\xcf\x1e\x6e\xe0\x19\x2b\x54\x25\x09\xa6\x09\x84\x2f\xdc\xa3\xd9\xef\x8f\xb8\x03\xc4\x82\xcf\x63\xf6\x94\x2f\x83\x92\xa9\xe0\xe9\x7d\xe2\x11\x47\x9d\xec\x76\x96\xf9\x7e\x3f\x33\xdb\x62\xa1\x44\x32\xbc\x7b\x7d\x37\x9c\xc1\x6e\xc7\x97\xf0\x2c\xfc\x11\x53\x56\x52\x9a\xb3\xfd\x7e\xa5\xdb\xe7\x10\x1f\x30\xad\x08\xfd\xd1\x6e\x87\xc2\xe0\x7e\x6f\xaa\x45\xc1\xc9\x6f\x79\xd9\x79\x99\xed\xf7\xf6\x00\x0d\xe8\xfd\x3e\x8e\xd8\x3c\x8e\x04\x9f\x37\x8b\xc7\x6a\x89\x2a\xd1\x59\x3e\x8e\xac\x83\xfc\x77\x39\xcb\x0f\xb8\x5a\x6d\x81\xd4\x3d\x4a\xf3\x1f\x72\x16\xe8\xbc\xa5\x36\xe5\x0d\x3c\x5b\x60\xf9\x1c\x5f\xc9\xa5\x72\x3e\x73\xd7\x8e\x5a\xb7\x71\x8a\x7b\x0f\x87\x69\x5c\x64\xb7\x6b\x24\xec\xf7\x1f\xe6\x28\x0e\x88\xdf\x63\x73\xe4\x30\x1d\xe8\xc6\xc9\xdf\x90\xde\xef\xa1\x47\xfd\x61\x9e\x54\xc7\x5b\x07\xb7\x8f\xf6\x2c\x84\xae\x82\x0e\x7f\xe3\x18\x86\x13\xde\xe3\x36\xf1\x76\xbb\xfe\xce\x66\x35\x65\x42\x2c\x98\x53\x8f\x3b\x5c\xb7\xe9\x0f\xb4\x0e\xbb\xe6\xc6\xd5\xce\xf3\x56\x7e\x07\xf9\xdf\x67\x82\x93\x9c\x46\xaa\x9c\xc2\xed\xf3\xa7\x12\xda\x97\x27\x39\xe2\xf6\x42\x8e\x28\x99\x44\x01\xee\x37\x30\x05\x13\xed\x73\x73\x57\xba\x28\x7d\xba\x25\xb0\x19\xbb\xc3\xd4\xa5\xfc\xf1\x0c\xd4\x1a\xf5\x52\xa8\xcd\x14\x58\x45\x6a\x06\x05\x7b\xe8\xaa\x9c\xdb\xf1\xb8\x03\x6c\xb9\x12\x5b\x08\x74\xd9\x48\xe3\xef\x15\x1a\x32\x5d\xee\xa9\x97\xdc\xaf\x4d\x41\x19\x4a\x83\xd9\x89\x12\xac\x3c\xab\x4b\x47\xd5\x22\x6d\xf5\x77\x11\xf5\x52\xa9\xa6\x98\xe8\x03\x68\x98\xf6\xaa\x1c\x6f\x1e\x93\x3e\x78\x0e\x65\xef\x55\x10\x68\x5b\xc6\x3f\x56\x0f\xd4\x31\xcc\x9e\xb9\x44\xd4\x75\x1d\x69\xfd\x12\xdc\x30\x8e\x28\xfb\x60\xb9\xd6\xd7\x16\xcc\xe0\xbb\x08\x77\xc5\xdd\x41\xb8\x1b\x7e\x9c\xf4\x1c\x99\xa6\x05\x32\x7a\x17\xf1\xcb\x4a\x66\xbd\xb3\xdf\xbd\xbe\xfb\x38\xe1\x95\xe4\x6b\xd4\x86\xd3\xf6\x5d\xa5\x63\x76\x10\x5f\x8f\xfb\x00\xe2\x88\xf4\xe3\x9e\x75\x78\x3c\xbb\xb7\xcd\xdf\xe6\xcf\x55\xdc\xb5\x20\x51\x04\xdf\x09\xb5\x60\x02\xd6\x16\xe0\x42\xa0\x01\x52\x60\x0b\x2a\xa0\x1c\x21\xad\xb4\x46\x49\x60\x88\x51\x65\x40\x2d\xdd\xec\xd2\x15\x8c\x57\x83\x35\xd3\xc0\x88\xb0\x28\x09\x12\x57\x49\xdb\x19\x83\x7a\xed\x9a\x01\x3b\xb0\x19\xbc\xbf\x56\xc7\x67\xcf\x6b\xc6\xed\x0d\x83\x04\x7e\xf9\x6d\x76\xe5\x00\x7d\x83\x4b\x2e\x11\x98\x55\x40\x6a\x5b\x01\xa0\x9c\x11\xa4\x1a\x19\xa1\x81\x54\x28\x53\xe9\x1a\xa7\xcd\x32\x60\xb1\xb6\x7c\x6a\xae\x76\xba\x74\x72\x5b\x16\x7e\xce\x4c\x3e\x72\xad\x80\x46\xaa\xb4\x3c\xac\xd4\xb3\x83\xa5\xd2\xe0\xdb\xcd\x3c\x19\xcf\x80\xc7\x2d\xc7\x50\xa0\x5c\x51\x3e\x03\x7e\x7d\xdd\x90\x0e\xf8\x12\xfc\x76\xfd\x17\xfe\x5b\x48\x0f\xa1\xe5\x0f\x49\x02\x07\x39\x03\x2b\xaa\xe1\x61\x4a\xc1\x53\xf4\xf9\x0d\x4c\x46\xb3\x7a\x6d\xa1\x91\xd5\x7d\x8c\x6b\x54\xdc\xcf\xfe\x6a\xb0\x9f\xf5\x75\xe0\x94\x7d\xa4\x85\x3a\x82\x1b\x60\xb0\xe2\x86\xa0\xd2\xc2\xea\xc1\xd2\xd5\x6a\x6f\xd4\xec\xa8\xfa\xe7\x3f\xcb\x2a\xcd\x43\x13\xed\x6b\xc8\x35\x8b\xd0\xa0\xcc\xfc\xbf\xbc\xf9\xfe\x75\x68\x48\x73\xb9\xe2\xcb\xad\xbf\xab\xb4\x98\xc2\x33\xdf\xfb\x1f\x5b\x97\x8f\x7e\x19\xff\x16\xae\x99\xa8\xf0\xa6\x31\xe9\x14\xda\x94\x6e\x2d\x3e\x75\xbf\x67\x32\x6f\xa0\x79\x9c\xc2\xb1\xf8\xfd\x68\x34\xbb\x94\xf7\x7a\x89\x5a\xa3\x41\xf2\x2d\x59\x93\x9e\x8e\x35\xc5\xa0\x40\xca\x55\x66\xb5\xa1\x31\x55\x52\x62\x4a\x50\x95\x4a\x36\x8a\x01\xa1\x8c\x69\x9d\xae\x5d\x4f\x4e\xdd\xa0\xa1\x4d\x40\xe2\x06\xfe\x8e\x8b\x37\x2a\xbd\x47\xf2\x7d\x7f\xc3\x65\xa6\x36\xa1\x50\x29\xb3\xe4\xb6\x73\x25\x95\x2a\x01\x49\x92\x40\xd3\xbc\x7b\x23\xf8\x3f\xf0\x36\xc6\xb6\xf1\x1e\x4c\xed\xa3\x7d\x1a\xc1\x35\x9c\x6e\xcf\x95\x21\xb8\x06\x2f\xaa\xaf\x92\xcd\x72\x9a\x22\x56\x72\x6f\x64\x6f\x41\x6b\x09\x25\x0b\x34\x86\xad\xb0\x8f\x14\xd7\x28\xa9\xf1\x31\x7b\x9c\xc2\xac\x20\x01\x67\xaf\x92\x69\x83\x35\x41\x68\xe3\x6e\xed\x6c\xd6\x5d\x1d\x51\x92\x80\xac\x84\x68\xfd\xb3\xbe\x09\xb3\xda\xfb\x7a\x84\xa1\x8b\x83\xf0\x49\x92\x80\x0d\x41\x56\xbf\x59\xbb\xc7\x7a\x40\x1d\x26\x47\xa1\x8d\x81\x07\xfa\xd1\xac\x75\xe3\x23\x3e\x98\x3d\xcd\x08\xb3\x53\x4e\x98\x5d\x60\xe5\xf2\xd0\xe3\x9c\xea\xac\xd5\x63\xe4\x26\x2e\xf0\x91\x55\xb1\x40\xfd\x38\xa3\x3a\x03\x35\x8c\x9c\x3a\x5f\x49\xea\xed\xbc\x81\xc9\x97\xa3\x0b\x7c\x51\x6b\xf5\x08\x5b\xa9\x68\xeb\xef\x04\xdb\xaa\x8a\xa6\x30\x24\x55\xbe\x74\x09\x63\x78\x03\x56\xca\x14\xba\xfd\x37\xae\xe8\x9f\xc2\xd0\x8d\xec\x3a\x2f\xd0\xed\xfa\x62\x3c\x1e\xdf\x40\xfb\xba\xe4\x8e\xd9\x1b\xa6\x2b\xdc\x5f\x40\x62\xaa\x34\x45\xf3\x88\xae\xde\x09\x4b\xc3\xa1\x43\xd3\x8c\x3f\x10\x4f\x17\xe2\x8f\x00\xc1\x67\x9f\xc1\xd9\x6a\xdf\x39\xa3\x08\xfe\xc6\xf4\x3d\xb8\xea\x4f\xe3\x9a\xab\xca\x1c\xd2\x45\xc1\x8d\xb1\x3d\x3d\x33\x90\x29\x89\x6e\xc7\xfb\x44\xf0\x33\x74\x0d\x11\xcc\x61\x7c\x0a\xcd\xc6\xba\x5e\x84\xbf\x10\xf8\x3b\xae\xfd\xa8\x3e\xd8\x1f\x24\x1d\xed\xe1\x05\xc2\x27\x09\x78\xde\x61\xdb\xd9\xba\x5d\x6e\xd8\x0c\x0c\xd2\x4f\xb5\xde\xfd\x26\xb1\x5d\x4a\x3e\xa3\x1b\x5b\xc8\x8e\x47\x47\xc2\xf7\xad\x2a\x5f\x94\x25\xca\x0c\x98\xdc\xba\xc8\xd6\xe9\x91\x4b\x52\xa0\x2a\x1b\x1d\x53\x26\x6c\x69\x2e\xd0\x45\x19\xb7\xd1\x2a\x33\x55\x45\xa1\x24\x24\x10\x4c\x66\x67\xc9\xaf\xa7\xb5\xee\x30\xa7\x66\xb8\xa0\xe5\x63\x53\x1c\x6b\xe8\x84\x34\x98\x1c\x29\xff\xc8\x2e\x97\x0c\x30\xe8\xf0\xf2\x56\x7f\x47\x46\x69\xad\xd2\xd7\x4f\x0f\x71\xbd\xfb\x7a\xf2\x4e\xc0\xbb\xc5\xb2\x32\xb9\x7f\x02\x6d\x34\x3b\xb6\xc0\x2b\x42\xcd\x08\x5d\x27\xe2\x34\x8e\x92\xb8\xc6\x33\xc5\x03\x93\xb6\x9c\x09\x34\xca\x0c\x75\x5b\x01\xd8\x46\xa6\xee\x3b\x7a\x86\x71\xdf\x2f\x7a\xae\xd2\x3b\xc7\x99\x16\x67\xc0\x61\x6e\xeb\x30\xe0\x41\xd0\x9d\xc0\x15\x4b\x4a\xa2\x6d\x4b\x4f\x3c\xdb\x79\x61\xcf\x0d\x2d\x29\x0a\x56\x1a\xcc\x20\x81\xfa\xad\xb3\x3f\x0a\x2b\xc9\x1f\xfc\x51\xd0\x8c\x4f\x39\xb4\xeb\x2e\xa7\x39\xe3\xd4\x98\xaf\x13\xf0\x62\xd2\xb6\xec\x1d\x7a\x70\x7d\xe9\x4e\xd9\xec\x38\x9c\xb7\xd2\xfb\x1b\x01\x62\xca\xe6\xae\x8d\xaa\x8b\xf1\x5f\x3d\xdb\xdd\xae\xb4\xaa\x64\x36\xb5\x25\x91\x7f\xc6\x94\xad\x19\x31\xed\x78\x8e\x66\x70\x20\x77\x4d\xf0\x14\x52\x6b\x95\x19\xd4\xbd\x96\xeb\x5f\xa1\xeb\x0e\xdd\x68\xa1\x74\x86\x3a\xd0\x2c\xe3\x95\x99\xc2\xe7\xe5\xc3\xec\xd7\xb6\x61\x76\x15\xfa\x13\x40\x4b\x8d\xf3\x33\x3c\x69\xea\x5e\x94\x5d\x83\x17\x47\x96\xe0\x69\x26\xdd\x41\xfb\xef\xbc\xe1\x42\x0f\x02\xdd\x1b\xea\x66\xbe\xe0\x59\x26\xd0\x82\x6d\x99\xdb\xdb\x66\x6d\x7e\xb8\x33\xc7\xe2\xa0\x69\x3c\x5a\xfa\x3d\xa0\x30\xf8\x28\x71\xd7\xbf\x0c\xad\xc1\x03\x7b\x50\xee\xf4\xdc\xb4\x42\x6e\x5a\x0f\x9d\x06\x9a\x6f\x15\x59\xa5\x5d\x15\xe4\x07\x8d\x43\xdd\xc0\xd0\xd8\x9a\x2c\x33\xc3\x51\x98\x57\x05\x93\xfc\x0f\xf4\x6d\x42\x19\xd5\x1a\x72\x0d\x91\x77\x1c\x57\xcf\x80\x1c\xfa\xea\x61\x9b\x98\x86\x8d\xe2\x86\xad\x35\xad\xe1\xe0\xd0\xa7\x0f\xdf\x43\x2b\x97\x25\x04\x0b\xa6\xa1\x3f\x08\xda\x6c\x09\x5a\x59\xc9\xed\xda\x82\xe9\x61\xdd\x04\xba\xba\x59\xaa\x4d\x32\xbc\x1d\x77\x00\x6b\xc3\x3a\xbb\x0e\x1b\xbf\x3a\x31\x80\x45\xd8\x5e\xc0\x39\xdc\x8e\x3f\x1e\x69\xc6\xe4\x0a\x4f\xd1\x93\xe6\x25\x66\xc0\x52\xe2\x6b\xfc\xd3\x0f\xf1\xd1\xca\x7d\x6f\x78\xd6\xef\x5a\xb5\x39\xb7\x3c\xc2\x6a\x57\x3b\xad\xfe\xaf\xbd\x57\x10\x39\xdd\x5e\x83\x77\xe1\x10\x8f\x78\xde\x11\xd1\xc9\xe5\x7d\xec\x5e\xbb\x5e\xde\xeb\x27\x09\x5b\x7e\x76\x6f\x9c\x46\x61\x4e\x85\xf0\xbd\x98\xdc\x57\x28\x8b\xb3\xdb\xed\x36\xd7\xd3\x87\x7a\x6b\xdf\xef\x1a\x6c\x8f\x8c\x27\xdd\x0d\xf4\xea\x88\xae\x03\x6a\x8b\x06\xb0\xdd\xd4\xde\x35\x54\x6f\x88\x69\x02\x06\x3f\xbf\x82\xaa\xcc\x18\xd9\x24\xa4\xc0\xa6\x38\x97\x8c\xba\x4f\x76\x0b\xa6\x0d\x2c\x95\xde\x30\x9d\x41\x25\x89\x0b\xbb\xbe\x05\xa6\xb1\xa9\xc9\x0c\xd2\x2b\x1b\x95\xd6\x4c\xf8\x27\x7d\xd6\x33\x7f\x18\xf6\x0d\x3b\x1c\x85\xc8\xd2\xfc\x94\xcc\x65\x9d\x4e\x62\x02\xaf\x5d\x0d\xee\x3f\xf3\x29\xe7\x66\x14\x32\x22\xed\x0f\x8f\x0c\x3e\x1c\x59\xdb\x4d\xba\xbe\xa7\xdb\x1c\xf7\xae\xcc\x53\xfb\x0f\x55\x6d\x93\xc1\x5b\xe2\xd4\x18\xbf\xf6\x9a\xe1\x4d\x8f\xef\xb1\xd3\x0c\x3f\x1d\x36\x26\x39\x5c\xda\x03\xfe\xe4\x02\x86\x23\xb6\x43\x7b\x77\x86\x27\x82\x59\x96\xbd\xb4\xf7\xc2\xf7\x2e\xdc\xde\xbe\x07\x8c\x1a\xc5\xd6\x11\xf7\x09\x8d\x72\x99\xe1\xc3\x63\xea\xe4\xd9\x70\x14\x9a\x6a\x51\xf7\xfe\xfe\x17\x4d\xb7\xd3\x12\x39\xb7\x3c\x0d\xe4\x67\xe9\xdf\x0a\x38\x2e\x01\x82\x93\x92\xe1\x89\x98\xef\x04\xda\xd3\xec\x6f\xac\x72\xc7\xa3\xe6\xc5\xd0\xb7\xc6\x56\x40\xdc\xe4\xc0\x60\x83\x0b\xe3\x7a\x73\x68\x3c\xd9\xbd\x21\xa9\xdf\x84\xbc\xf8\xe1\x55\xf7\x36\xa4\xf3\x74\x5b\x84\x74\x1f\xc7\xcf\xdf\x35\x5c\xfc\x16\xbf\xd9\x6c\xc2\x95\x52\x2b\x51\x7f\x85\xef\x5e\x46\xd8\x46\x3d\x7c\x6b\x3c\x60\x66\x2b\x53\xc8\x70\x89\x7a\xde\x63\x5e\xbf\xa1\x88\xa3\xe6\x03\x72\x54\xff\x77\x97\x7f\x05\x00\x00\xff\xff\x1d\xd7\x27\x7a\xff\x22\x00\x00") +var _faucetHtml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xd4\x3a\x6b\x6f\xe3\x38\x92\x9f\xd3\xbf\xa2\x46\xd7\x3b\xb6\xaf\x23\xc9\xef\x38\xb6\xe5\x41\x3b\x49\xef\xe6\x80\xeb\x6d\x6c\xf7\xe0\xf6\x30\x3b\x38\x50\x62\xd9\x66\x47\x22\x35\x24\xe5\xc4\x6b\xf8\xbf\x1f\x48\x3d\x2c\x3f\x92\xe9\xc7\x2c\x0e\x97\x0f\x8e\x48\x16\xeb\xcd\xaa\x62\x49\xd3\x1f\x6e\xff\x7a\xf3\xe9\xbf\x3f\xdc\xc1\x4a\x27\xf1\xec\xd5\xd4\xfc\x83\x98\xf0\x65\xe0\x20\x77\x66\xaf\x2e\xa6\x2b\x24\x74\xf6\xea\xe2\x62\x9a\xa0\x26\x10\xad\x88\x54\xa8\x03\x27\xd3\x0b\x77\xe4\xec\x17\x56\x5a\xa7\x2e\xfe\x96\xb1\x75\xe0\xfc\xdd\xfd\xf9\xad\x7b\x23\x92\x94\x68\x16\xc6\xe8\x40\x24\xb8\x46\xae\x03\xe7\xfe\x2e\x40\xba\xc4\xda\x3e\x4e\x12\x0c\x9c\x35\xc3\xc7\x54\x48\x5d\x03\x7d\x64\x54\xaf\x02\x8a\x6b\x16\xa1\x6b\x07\x97\xc0\x38\xd3\x8c\xc4\xae\x8a\x48\x8c\x41\xc7\x99\xbd\x32\x78\x34\xd3\x31\xce\xb6\x5b\xef\x3d\xea\x47\x21\x1f\x76\xbb\x31\xbc\x23\x59\x84\x7a\xea\xe7\x6b\x16\x2c\x66\xfc\x01\x56\x12\x17\x81\x63\x98\x55\x63\xdf\x8f\x28\xff\xac\xbc\x28\x16\x19\x5d\xc4\x44\xa2\x17\x89\xc4\x27\x9f\xc9\x93\x1f\xb3\x50\xf9\xfa\x91\x69\x8d\xd2\x0d\x85\xd0\x4a\x4b\x92\xfa\x3d\xaf\xe7\x5d\xf9\x91\x52\x7e\x35\xe7\x25\x8c\x7b\x91\x52\x0e\x48\x8c\x03\x47\xe9\x4d\x8c\x6a\x85\xa8\x1d\xf0\x67\xdf\x46\x77\x21\xb8\x76\xc9\x23\x2a\x91\xa0\xdf\xf7\xae\xbc\xb6\x25\x59\x9f\x7e\x99\xaa\x21\xab\x22\xc9\x52\x0d\x4a\x46\x5f\x4c\xf7\xf3\x6f\x19\xca\x8d\xdf\xf3\x3a\x5e\xa7\x18\x58\x3a\x9f\x95\x33\x9b\xfa\x39\xc2\xd9\x77\xe1\x76\xb9\xd0\x1b\xbf\xeb\xf5\xbd\x8e\x9f\x92\xe8\x81\x2c\x91\x96\x94\xcc\x92\x57\x4e\xfe\x61\x74\x9f\xb3\xe1\xe7\x63\x13\xfe\x11\xc4\x12\x91\x20\xd7\xde\x67\xe5\x77\xbd\xce\xc8\x6b\x97\x13\xa7\xf8\x2d\x01\x63\x34\x43\xea\xc2\x5b\xa3\xd4\x2c\x22\xb1\x1b\x21\xd7\x28\x61\x6b\x66\x2f\x12\xc6\xdd\x15\xb2\xe5\x4a\x8f\xa1\xd3\x6e\xff\x69\x72\x6e\x76\xbd\xca\xa7\x29\x53\x69\x4c\x36\x63\x58\xc4\xf8\x94\x4f\x91\x98\x2d\xb9\xcb\x34\x26\x6a\x0c\x39\x66\xbb\xb0\xb3\x34\x53\x29\x96\x12\x95\x2a\x88\xa5\x42\x31\xcd\x04\x1f\x1b\x8f\x22\x9a\xad\xf1\x1c\xac\x4a\x09\x3f\xd9\x40\x42\x25\xe2\x4c\xe3\x11\x23\x61\x2c\xa2\x87\x7c\xce\x9e\xdf\xba\x10\x91\x88\x85\x1c\xc3\xe3\x8a\x15\xdb\xc0\x12\x82\x54\x62\x81\x1e\x52\x42\x29\xe3\xcb\x31\x0c\xd3\x42\x1e\x48\x88\x5c\x32\x3e\x86\xf6\x7e\xcb\xd4\x2f\xd5\x38\xf5\xf3\x50\xf5\xea\x62\x1a\x0a\xba\x31\x33\x94\xad\x81\xd1\xc0\x91\x18\x91\x54\x47\x2b\xf2\x3f\x18\xa3\xb1\x88\x31\x05\x65\x6b\x0b\x5c\x02\xe5\x91\x87\xce\x05\xdd\x38\x10\xc5\x44\xa9\xc0\x39\xb2\x8b\x8d\x5b\xf9\x8e\x02\xc0\x6c\x22\x8c\x97\x4b\x07\x6b\x52\x3c\x3a\x60\xb9\x0b\x9c\x9c\x73\x37\x14\x5a\x8b\x64\x0c\x1d\x23\x53\xb1\xe5\x08\x5f\xec\xc6\x4b\xb7\xd3\x2d\x17\x2f\xa6\xab\x4e\x89\x44\xe3\x93\x76\xad\x51\x2b\x73\x3a\xb3\x29\x2b\xf7\x2e\x08\x2c\x88\x1b\x12\xbd\x72\x80\x48\x46\xdc\x15\xa3\x14\x79\xe0\x68\x99\xa1\x91\x98\xcd\xa0\x1e\x25\xab\x20\xb9\xea\x94\x9c\xe4\x4a\x39\x7e\x3c\x92\xe9\x79\xb6\x47\x50\x3c\x88\xc5\x42\xa1\x76\x6b\x52\xd4\x80\x19\x4f\x33\xed\x2e\xa5\xc8\xd2\x6a\xfd\x62\x6a\x67\xad\x21\x32\x19\x3b\x45\x5e\xb0\x8f\x7a\x93\x16\xc2\x57\x76\x59\x08\x99\xb8\x46\xf7\x52\xc4\x0e\xa4\x31\x89\x70\x25\x62\x8a\x32\x70\xee\x2d\x9e\x8d\xc8\x24\xcc\xdf\xcf\xe1\x63\x42\xa4\x86\x9b\x15\x61\x1c\x08\xa5\xc6\x89\x3d\xcf\xab\xd1\xb5\x1e\x7d\xca\x99\x1b\x6a\xbe\x87\xba\x98\x86\x99\xd6\xa2\x02\x0c\x35\x87\x50\x73\x97\xe2\x82\x64\xb1\x06\x2a\x45\x4a\xc5\x23\x77\xb5\x58\x2e\x4d\xc6\xcb\x79\xce\x37\x39\x40\x89\x26\xc5\x52\xe0\x94\xb0\xa5\x91\x88\x4a\x45\x9a\xa5\x85\x99\xf2\x49\x7c\x4a\x09\xa7\x48\x8d\x51\x63\x85\xce\xec\xcf\x6c\x8d\x90\xa0\x11\xe9\xe2\xd8\xe2\x11\x91\xa8\xdd\x3a\xca\x13\xbb\x4f\xfd\x9c\x95\x5c\x20\x28\xfe\xa6\x59\x5c\x62\xaa\x04\x48\x90\x67\x70\x30\x72\xa5\x89\x35\x95\x2e\x00\xb6\x5b\x49\xf8\x12\xe1\x35\xa3\x4f\x97\xf0\x9a\x24\x22\xe3\x1a\xc6\x01\x78\x6f\xed\xa3\xda\xed\x0e\xc8\x00\x4c\x63\x06\xb3\x29\x79\xc9\x8f\x41\xf0\x28\x66\xd1\x43\xe0\x68\x86\x32\xd8\x6e\x0d\xf6\xdd\x6e\xa2\x36\x49\x28\xe2\xa0\x31\x7f\x3f\x6f\x4c\x54\x16\x26\x4c\x37\x5b\xce\x6c\xbb\x2d\xe8\xee\x76\x53\x9f\xcc\xa6\x7e\xcc\x66\xdb\x2d\x72\x7a\x44\x7b\xea\x67\xf1\xde\xd6\xbe\x31\xf6\xff\x37\xd3\x7f\xc0\xe5\x72\x03\x5a\x3c\x20\x57\xff\x47\xa6\xdf\x9b\x3c\x37\xc7\x25\xbc\x0e\x31\xed\xe2\x3d\x5f\x08\x6b\xf8\x79\x39\x2a\x6d\x6f\x15\x17\xb3\x2f\x36\x7a\x61\xe6\xed\xb6\xa0\xb0\xdb\x4d\xe0\xc0\xda\x15\xbd\xc2\xc9\x3e\x6a\xb9\xdb\x41\x0d\xfe\x5b\xdd\xa0\x16\xe8\xbe\x30\xfe\x1d\xc5\x74\x2d\xd2\x31\xf4\xba\xb5\x80\x7e\x2e\x34\x0e\x8f\x42\x63\xef\x2c\x70\x4a\x38\xc6\x60\x7f\x5d\x95\x90\xb8\x7c\x2e\x9c\xad\x16\xb6\x8e\x37\xb9\xa1\xcd\x5b\x05\x6b\x55\xee\x6c\x4f\x40\xac\x51\x2e\x62\xf1\x38\x06\x92\x69\x31\x81\x84\x3c\x55\xf5\x43\xaf\xdd\xae\xf3\x6d\x8a\x69\x12\xc6\x58\x24\xcd\xdf\x32\x54\x5a\x55\x41\x37\x5f\xb2\xbf\x26\xf6\x52\xe4\x0a\xe9\x91\x36\x0c\x45\xe3\x77\x16\xaa\xa6\xf1\xbd\x8e\xcf\xf1\xbe\x10\xa2\xca\xae\x75\x36\x0a\xd4\xb5\xea\xc1\x99\x4d\xb5\xdc\xc3\x5d\x4c\x35\xfd\xaa\xec\x28\x4d\xc9\xfc\x5c\x72\xcc\x03\x82\x91\x3d\x45\x94\x79\xbd\x66\x3c\x05\xec\x70\xea\x6b\xfa\x1d\x94\x4d\x20\x08\x89\xc2\x2f\x21\x6f\x2b\xa7\x3d\x79\x3b\xfc\x5e\xfa\x2b\x24\x52\x87\x48\xf4\x97\x30\xb0\xc8\x38\xad\xc9\x3f\x7f\x3f\xff\x5e\xf2\x19\x67\x6b\x94\x8a\xe9\xcd\x97\xd2\x47\xba\x67\x20\x1f\x1f\xb2\x30\xf5\xb5\x7c\xd9\xd3\xfe\x05\x47\xfb\xf7\x6a\xb5\xde\xec\x2f\xe2\x11\xa8\x40\x05\x7a\xc5\x14\x98\x4a\xeb\xa7\xa9\xbf\xea\x55\x20\xa9\x89\x89\x87\xd7\x41\x8d\x4a\x73\xd4\x5e\xa8\x22\x15\x11\x9e\x5f\x2a\xf2\x5a\xc5\x6f\x3f\x0d\x23\x1c\xd1\xb7\xdd\xd1\x5d\x77\x31\x1a\xf6\xfb\xdd\xf6\xa8\xdf\x8e\xde\x5d\xf5\xfb\x57\x7d\x7c\xb7\x18\x2c\x6e\x47\xed\xbb\xe1\x60\x3e\x72\x66\xf3\x4f\x37\x26\x0a\x5e\x7e\x25\x01\x3a\x1c\x46\xc3\x79\xff\x5d\x3b\xc4\xd1\xcd\xdd\x20\xec\x5d\xdf\x0e\xba\x77\xed\x77\xb4\xd3\xeb\xf7\xa3\xde\xe8\xfa\xba\x7b\x3d\xef\x5d\x8d\x9c\xd9\xdd\xa7\xbf\x7c\x0b\x01\x32\xea\x0d\xae\x06\xfd\xeb\xf6\xed\x15\x5d\xf4\xef\xba\xef\xfa\x57\xe1\xd5\x6d\x6f\x84\x8b\xde\xa0\x43\xba\x57\xdd\x6e\xf4\xb6\x3f\x08\xaf\x9d\xd9\xdf\xff\xf6\xe1\x5b\x08\x20\xed\xf6\x17\x51\x6f\x48\x07\x88\xdd\x4e\x07\x49\x77\x40\x46\xed\x6e\xef\x7a\x11\x8e\xa2\x7e\xb4\xa0\xa3\xf6\xa2\xd3\x45\x74\x66\xf3\x9f\x3f\xde\x7e\x0b\x85\x5e\xef\x6a\xd8\x69\xd3\xee\x55\x34\x1c\x75\xef\x7a\xfd\xab\x9b\xeb\xe8\x76\xd8\x9e\xdf\xf6\xc3\x5e\xd8\x69\x5f\xdd\x5c\xd3\x5e\x9f\xde\x52\x67\xf6\xf3\xc7\xdb\x4f\xdf\x42\x61\xd8\x1f\xf4\xfb\xd7\xc3\x6b\xa4\x57\x77\xf3\xc5\x60\xd1\x1e\xf5\x86\x57\xd7\xdd\x5e\xaf\xd7\x1d\xf4\x06\xc3\xbb\xf0\xee\xaa\x37\xba\xee\xb5\x2d\x85\x6f\xb2\xf3\xdd\xcd\x80\xde\x84\x83\xdb\x70\xd1\x9f\x77\x3a\xfd\x9b\x6b\xda\x7e\x37\x1c\xcc\xa3\x9b\xb7\x61\xff\xfa\xee\x66\xd0\x7f\x37\x7c\xdb\x1e\x0d\xaf\x9c\xd9\xed\xdb\x7b\x43\x00\x88\x44\x60\x4a\x65\x48\x81\x28\x98\xdf\x7d\xe8\xb6\xf3\x42\xc4\x9b\xfa\x69\xcd\xa3\xe1\xc6\x64\x71\xd0\x02\x96\xa8\x81\xa2\x26\x2c\x06\x12\x8a\x4c\xc3\x09\x8f\x4b\xa6\x57\x59\x68\x59\x0b\x79\xe8\x46\xa6\x32\xf7\xe7\x77\x1f\x94\x1f\xc6\x22\xf4\x13\xa2\x34\x4a\xdf\xd2\xf2\x12\xea\xcc\xec\x93\xe1\x26\xa7\x59\x23\xfa\x31\x4b\x53\x21\x35\xdc\x32\x15\x09\x49\xc7\x87\xb4\xc6\xbe\x4f\xf3\x05\x6f\xb9\x34\xa4\x2c\x25\x67\x06\x67\x66\xc1\x4a\x5b\x93\x69\xbb\x65\x0b\xf0\xfe\x56\x5e\x1b\x77\xbb\x29\x26\xb3\x4f\x2b\x84\x85\xbd\x32\x01\x53\x20\x33\xce\x19\x5f\x82\xc4\x9b\x1c\x08\x52\x29\x34\x46\xe6\x4a\x0c\x64\x49\x18\x57\x1a\x42\xa1\x95\x37\xf5\x31\x39\xa8\x4a\xce\x07\xa3\xea\xa9\xba\x9a\x96\x3d\x08\xbb\xec\xfb\xf0\xe7\x58\x84\x24\x86\xb5\x89\x9f\x61\x6c\x42\x8c\x00\x73\xed\x01\xbd\x42\x88\x32\x29\x91\x6b\x50\x9a\xe8\x4c\x81\x58\xd8\xd9\x9c\x5f\xb3\x7f\x4d\x24\x10\xad\x31\x49\x35\x04\xc5\x0d\xda\xcc\x29\x94\xeb\xa2\x2f\x60\x86\xa6\xfa\x3e\x5c\xcf\x2b\x33\xc7\xa9\x66\xca\xc2\x00\x02\xf8\xe5\xd7\x6a\xb6\x50\xd5\xe4\x55\xc1\xec\x2d\x2e\x18\x47\x20\x26\x76\xe7\x4a\xd1\x2b\xa2\x21\x92\x48\x34\x2a\x88\x62\xa1\x32\x99\xcb\x60\x6a\x4e\x30\x72\x94\x98\x4b\x9c\x66\x21\xb5\xfc\x94\x48\x9a\x2b\xa2\x56\xad\xa2\x45\x20\x51\x67\x92\xef\xd7\xca\xf9\x8b\x85\x90\xd0\x34\x08\x58\xd0\x9e\x00\x9b\x96\x78\xbd\x18\xf9\x52\xaf\x26\xc0\xde\xbc\xa9\x80\x2f\xd8\x02\x9a\x25\xc4\x2f\xec\x57\x4f\x3f\x79\x86\x0a\x04\x01\xd4\xa9\x59\x82\x05\x1e\x95\xc6\x2c\xc2\x26\xbb\x84\x4e\x6b\x52\xae\x86\x12\xc9\x43\x39\x2a\x2c\x9d\xff\xb3\xbf\xbb\x5c\x35\x54\x44\x99\x6d\x0a\x2d\x51\xdf\xe5\xdd\x88\xf9\xe6\x9e\x36\x0f\xfa\x0f\x2d\xcf\x26\x22\xaf\xe8\xa5\x40\x00\x0e\x17\x1c\x9d\x1c\x45\x6e\x84\x42\xe1\x37\x24\x8e\x43\x12\x3d\xd4\x95\x54\xb2\xbc\x2a\x60\x3c\x89\x9c\xa2\x6c\x36\x4e\x1a\x21\x8d\xcb\x52\xba\x86\x62\x1a\x1f\x70\xd3\x80\x31\x34\xb6\xdb\xba\xf3\x37\x2e\x0b\x90\xa8\xa0\x65\x60\x88\x52\x6c\xc9\x4b\xea\x39\xc4\x2e\x57\xc6\x6e\xcf\xe6\x21\x54\x9d\xc7\x65\x81\xbe\xe4\xf5\x5b\xf5\x92\xd7\x4a\x93\x97\x71\x9c\x36\x80\x9e\xd7\xb0\x41\x54\x40\x43\x00\xcb\xca\xaf\x73\xc1\x0e\x9c\xdb\x9e\xb0\x03\xf7\xce\xef\x2c\x0a\x08\x2c\x99\xd2\x90\xc9\xd8\x38\xb8\x81\xcb\xcf\x59\x75\xaa\x2c\xdc\x39\x9b\xe5\x70\x9e\x42\x4e\x9b\xff\xf1\xf1\xaf\xef\x3d\xa5\x25\xe3\x4b\xb6\xd8\x34\xb7\x99\x8c\xc7\xf0\xba\xe9\xfc\x5b\x26\x63\xa7\xf5\x4b\xfb\x57\x6f\x4d\xe2\x0c\x2f\x8b\x43\x3a\x86\xf2\x7a\x66\x4e\xf1\xd8\xfe\x9e\x44\xb2\xcb\xf2\xa4\x8e\xcb\x87\x22\x34\xed\x5a\xad\xc9\x09\xf4\xb1\x1b\x29\xd4\x4d\x03\x56\x05\xb3\x63\x95\x10\x48\x50\xaf\x04\x35\x62\x4b\x8c\x04\xe7\x18\x69\xc8\x52\xc1\x0b\x0d\x40\x2c\x94\xaa\x79\x71\x01\xf1\xac\x26\x20\x00\x8e\x8f\xf0\x5f\x18\x7e\x14\xd1\x03\xea\x66\xb3\xf9\xc8\x38\x15\x8f\x5e\x2c\x22\x62\x36\x78\x26\xf0\x8a\x48\xc4\x10\x04\x01\x14\x89\xc6\x69\xc1\x4f\xe0\x3c\x2a\x93\x72\x1c\x18\x9b\x47\xf3\xd4\x82\x37\x70\xbc\x7d\x25\x94\x86\x37\xe0\xf8\x79\xb0\x34\x17\x2f\xa9\x7d\x92\x32\xa7\x95\x3b\x72\x69\x13\xc1\x13\x54\x8a\x2c\xb1\xce\x2d\xae\x91\xeb\x2a\x46\x18\xa1\x12\xb5\x84\x00\xac\xed\x52\x22\x15\xe6\x20\x9e\xb9\x00\x94\xc1\xc2\x84\x1c\x0b\x16\x04\xc0\xb3\x38\xde\xc7\x98\x3c\xa6\x4d\xca\xe8\x71\x00\xee\xd9\xb2\x1c\x7e\x08\x02\x30\xf5\xb0\xd1\x37\xdd\xef\x34\x7e\x91\xd7\xed\x2d\xcf\x94\xe4\xfb\x1d\xad\x49\x3d\x18\x1d\x60\x43\xfa\x7b\xe8\x90\x1e\xe3\x43\xfa\x0c\x42\x7b\x4d\x7a\x09\x5f\x7e\xad\xaa\xa1\xb3\x13\xcf\x60\xe3\x59\x12\xa2\x7c\x09\x5d\x7e\xf4\x0b\x74\x56\xd5\xf7\x5c\xd7\xf6\x5e\x42\x67\xd8\x7a\x06\x3b\x4a\x29\x9e\x45\xce\x85\xde\x34\xb7\x31\xd9\x88\x4c\x8f\xa1\xa1\x45\x7a\x63\xef\x35\x8d\x4b\x30\xb4\xc6\x50\x61\xb8\xb4\xed\x9e\x31\x34\xec\xc8\xac\xb3\x04\xed\xae\x41\xbb\xdd\xbe\x84\xb2\x71\x3e\x27\xe6\x3c\xca\x0c\x77\xcf\xf0\xa3\xb2\x28\x42\xf5\xac\xf6\xbe\x88\xa3\x02\x47\xc5\x53\x31\xfe\x0e\xae\xaa\x54\x7f\xc0\x16\xfc\xf8\x23\x9c\xac\x1e\xba\xb1\xef\xc3\x7f\x12\xf9\x00\xb6\x85\x21\x71\xcd\x44\xa6\xf6\x85\x43\xc2\x94\x32\xb5\x13\x51\x40\x05\xc7\x62\xcf\xd7\x65\xed\x13\x1e\x0b\x30\x98\x41\xfb\x98\x41\x13\x29\x6b\x59\xfd\x4c\xb2\xaf\xe1\x3d\xcc\xe3\x17\xbb\x3a\xbd\x83\x9d\x2c\x41\xf8\x21\x00\xc7\xa9\x6f\x3e\x81\x30\x00\x15\xb2\x0b\x85\xfa\x53\x6e\x8b\x66\x51\xdc\x9c\x2b\x3d\x5a\x97\xd0\x6b\xb7\xdb\xad\x13\x26\x76\x7b\xf5\xbe\x4d\x53\xe4\x14\x08\xdf\xd8\xf8\x58\xe9\x96\x71\x2d\x40\x64\x26\xce\x46\x24\x86\x48\xc4\x71\x5e\x94\x16\x5b\x6d\xad\x26\x92\x44\x70\x08\xc0\xed\x4c\xce\x14\x41\x35\x4d\xd6\x44\x3b\x36\xcf\x19\xdd\x1f\x9b\xe8\x50\x67\x47\xc0\x6e\xe7\xc0\x28\x07\xf6\x3a\x6f\x98\x8b\x8a\x6f\xb6\xd7\xe8\x91\xb9\xf6\xf6\x3a\xd6\x59\x8d\xff\x1c\xcf\x9b\xce\x17\x8a\x51\x2d\xa7\x99\x5a\x35\x8f\x18\x6d\x4d\x4e\x6d\x73\xaf\x51\x12\x8d\xb6\xf5\x66\x6d\x81\x5c\x33\x89\x27\x26\x01\xc2\x4d\xd1\xeb\xe6\xe5\x59\x59\x4e\x50\x73\x34\x6c\x5b\xe3\xc0\x64\xf6\xbd\xf8\x81\x3b\x7d\xe5\x81\xb1\x15\xb5\xe0\x08\x00\x70\x74\x08\xac\xa3\x1e\x78\xaa\x01\xc6\x98\xa4\x0a\x29\x04\x90\xbf\xc7\x6c\xb6\xbc\x8c\xb3\xa7\x66\xcb\x2d\xc6\xc7\x38\xca\xf5\x49\x79\x4d\xbb\x28\xd9\x7e\x13\x80\x33\xd5\x12\x18\x0d\x1a\x0e\xbc\x39\x77\x04\x4d\x0a\x6e\xcc\xf6\x1c\xd4\xb7\x02\x4c\x35\x9d\xd9\xe6\x4b\xde\xa1\xf9\x87\x63\xea\xc9\xa5\x14\x19\xa7\x63\x53\x66\x35\x4f\xd0\x92\x35\xd1\x44\x5a\xac\xad\x09\xec\xc1\x5d\xc5\xfe\x89\x63\x88\x8c\x71\x26\x90\xf7\x16\x6d\x8f\x07\xaa\xae\xa8\x1d\x85\x42\x52\x94\xae\x24\x94\x65\x6a\x0c\xfd\xf4\x69\xf2\x8f\xf2\xbd\xa1\xed\x44\xbd\xc8\x6a\x2a\x71\x76\xc2\x51\x14\xd9\x57\x25\x6f\xc0\x99\xfa\x06\xe0\xf7\xd0\x54\xc2\xd6\xdf\x9f\xc2\x99\x7e\x1b\x54\x2f\x2a\x8b\xf9\x84\x51\x1a\xa3\x61\x78\x8f\xde\x1c\x46\x63\xff\xfa\x91\x3a\x24\x09\x45\xa3\x6d\xbf\x67\x07\x18\x2b\x7c\x61\x43\xd5\xb3\x6b\x18\x07\x70\x8d\xc8\xcc\xea\xbc\xe8\x92\xd9\x69\xd9\xb0\xba\x28\xde\x86\xd3\x4c\xda\xc2\xab\xe9\x16\x0e\x76\x09\x0d\x65\x0a\x41\xaa\x1a\x2d\x6f\x95\x25\x84\xb3\x7f\x62\xd3\xe4\xa5\x56\xae\x2b\xdb\x04\x74\x4e\x43\xf2\x09\x33\xfb\xee\x5c\xa3\xcc\x71\x8d\x42\x89\x8d\xd2\xba\xc6\x90\xb5\x37\xc9\x8d\xaf\xd4\xd0\x79\x2a\x6e\x48\x24\xd4\x07\x6e\x99\x7c\x41\x0a\x43\xbd\x5c\x0b\x89\x6c\xe4\x0d\x50\x5b\xba\x73\xf1\x18\x34\x7a\xed\x8a\xc9\xdc\xd0\xd6\xce\x8d\xc2\xd7\x4e\x8c\x61\xb8\x2c\x8f\xe6\x0c\x7a\xed\x3f\x82\x5b\x4a\xf8\x12\x8f\x25\xd0\x92\xa5\x48\x81\x44\x9a\xad\xf1\x5f\x20\xc8\x1f\xa0\xe4\xaf\x66\xd1\xf8\x61\xa9\x3c\xeb\xa6\x07\xfc\x9a\xd5\x4a\xb7\xff\x6e\xce\x1b\xf8\x56\xc3\x6f\xc0\x39\x2b\xc8\xb3\x9e\x78\x04\x78\x74\xb4\x9f\x3f\xf7\xb6\xab\xed\x1c\xe7\x14\x53\xed\x56\xef\x63\x5a\xde\x4a\x27\x71\xd3\x99\x6a\xfb\x9d\x83\xe1\xb9\xc2\x60\x11\xe4\xd3\x87\x25\xdd\xee\xf0\x22\x13\xc5\x42\xe1\xd1\xa5\x0b\x6a\xc5\x49\x75\x31\x2b\x2b\x11\xd8\xed\x3f\x07\xf1\x7d\xf8\xa8\x89\xd4\x40\xe0\xe7\x7b\xc8\x52\x4a\xb4\xc9\x5e\x02\x4c\x7e\xb4\x59\xac\xfa\x5e\x24\x24\x52\xc1\x42\xc8\x47\x22\x29\x64\x5c\xb3\xd8\xac\x6f\x6c\x67\xb1\x2c\xfd\x14\xea\x7b\x13\xc5\xd6\x24\x6e\x9e\x5c\x02\x5f\x37\x1b\x5e\xdd\xe4\x8d\x96\x87\x24\x5a\x9d\x02\xda\x8c\x55\xd1\x0d\xe0\xbd\xbd\x02\x34\x5f\x37\xf5\x8a\xa9\x96\x47\xb4\x96\xcd\xc6\x81\x33\x34\x5a\xc6\xae\x9d\xda\x95\xac\xda\x3e\x3d\x38\x56\x2f\xe1\xd8\x17\xd3\x55\x21\x50\x82\x47\x4a\x35\x73\xbf\x6a\x5c\xd6\x70\x1f\xba\x55\xe3\x4f\x8d\xca\x50\xfb\xe3\xbd\x97\x23\x38\xcb\xc9\x01\xea\x86\x39\x65\x8d\x13\xf2\x84\xd2\x1b\x73\x7e\x9a\xce\x99\x93\x7e\xec\x1d\xad\x4a\xd9\x79\xbc\x7e\x51\xcb\x8c\x53\x7c\x7a\x4e\xc5\x8c\x36\x5a\x9e\xca\xc2\xbc\x6d\xd1\x1c\x54\x17\xb0\x12\xcc\x3a\xef\x71\x2a\x38\x29\x28\x0c\x89\xc3\xa2\xc2\x3d\x2a\x42\x5e\xc8\x1a\x05\xc9\x5c\xaa\xdd\xa5\x51\x78\xbb\x55\x75\x26\xef\x94\x29\xae\x98\x5a\x01\x81\x47\x0c\x95\x6d\x2b\x40\xe1\xef\xb6\x93\x93\x77\x6c\xde\x7e\xb8\xaf\x75\x6d\xaa\x13\xd1\xb4\xd8\xab\x4f\xb9\xce\xb5\x4c\xce\x7e\x3b\xf6\x59\x79\x55\x23\x25\x12\x89\xdf\xf1\x49\xca\xbc\xcf\xea\x27\xc1\x63\x41\x68\x70\xd2\xd1\xfb\x31\x2f\x0b\x03\x7c\x4a\x63\x16\x31\xed\x58\xa1\x88\xda\xf0\x08\x28\x2e\x50\xce\x6a\x4c\x14\x0d\x99\xa9\x9f\x7f\xfb\x34\xf5\xf3\x0f\x3a\xff\x37\x00\x00\xff\xff\x9e\xad\x18\xb9\xe1\x29\x00\x00") func faucetHtmlBytes() ([]byte, error) { return bindataRead( @@ -85,7 +84,7 @@ func faucetHtml() (*asset, error) { } info := bindataFileInfo{name: "faucet.html", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} - a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x39, 0x4d, 0x5d, 0x6d, 0x7f, 0xf1, 0x26, 0x19, 0x7, 0xee, 0xd2, 0xb3, 0x2, 0xdf, 0xd2, 0x8c, 0x36, 0x87, 0x8e, 0x17, 0x50, 0xb6, 0x8f, 0xb0, 0xb5, 0xce, 0x73, 0xcc, 0x24, 0xd3, 0xd6, 0x8e}} + a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x52, 0x9f, 0x7a, 0x51, 0x16, 0x30, 0x5c, 0xd0, 0xef, 0xb1, 0xd6, 0xf2, 0xd6, 0xea, 0xe6, 0x6d, 0xd, 0xca, 0x7f, 0x57, 0x5b, 0xb7, 0x2c, 0xab, 0xe8, 0xca, 0x73, 0xa2, 0x0, 0xc9, 0xa9, 0x75}} return a, nil } @@ -190,11 +189,13 @@ const AssetDebug = false // directory embedded in the file by go-bindata. // For example if you run go-bindata on data/... and data contains the // following hierarchy: -// data/ -// foo.txt -// img/ -// a.png -// b.png +// +// data/ +// foo.txt +// img/ +// a.png +// b.png +// // then AssetDir("data") would return []string{"foo.txt", "img"}, // AssetDir("data/img") would return []string{"a.png", "b.png"}, // AssetDir("foo.txt") and AssetDir("notexist") would return an error, and @@ -244,7 +245,7 @@ func RestoreAsset(dir, name string) error { if err != nil { return err } - err = ioutil.WriteFile(_filePath(dir, name), data, info.Mode()) + err = os.WriteFile(_filePath(dir, name), data, info.Mode()) if err != nil { return err } diff --git a/cmd/geth/blsaccountcmd.go b/cmd/geth/blsaccountcmd.go new file mode 100644 index 0000000000..45d11269e7 --- /dev/null +++ b/cmd/geth/blsaccountcmd.go @@ -0,0 +1,558 @@ +package main + +import ( + "context" + "encoding/hex" + "encoding/json" + "fmt" + "io/ioutil" + "os" + "path/filepath" + "strings" + + "github.com/google/uuid" + "github.com/logrusorgru/aurora" + "github.com/prysmaticlabs/prysm/v3/crypto/bls" + "github.com/prysmaticlabs/prysm/v3/encoding/bytesutil" + "github.com/prysmaticlabs/prysm/v3/io/prompt" + "github.com/prysmaticlabs/prysm/v3/proto/eth/service" + "github.com/prysmaticlabs/prysm/v3/validator/accounts" + "github.com/prysmaticlabs/prysm/v3/validator/accounts/iface" + "github.com/prysmaticlabs/prysm/v3/validator/accounts/petnames" + "github.com/prysmaticlabs/prysm/v3/validator/accounts/wallet" + "github.com/prysmaticlabs/prysm/v3/validator/keymanager" + "github.com/prysmaticlabs/prysm/v3/validator/keymanager/local" + keystorev4 "github.com/wealdtech/go-eth2-wallet-encryptor-keystorev4" + "gopkg.in/urfave/cli.v1" + + "github.com/ethereum/go-ethereum/cmd/utils" + "github.com/ethereum/go-ethereum/signer/core" +) + +const ( + BLSWalletPath = "bls/wallet" + BLSKeystorePath = "bls/keystore" +) + +var ( + au = aurora.NewAurora(true) +) + +var ( + blsCommand = cli.Command{ + Name: "bls", + Usage: "Manage BLS wallet and accounts", + ArgsUsage: "", + Category: "BLS ACCOUNT COMMANDS", + Description: ` + +Manage BLS wallet and accounts, before creating or importing BLS accounts, create +BLS wallet first. One BLS wallet is enough for all BLS accounts, the first BLS +account in the wallet will be used to vote for fast finality now. + +It only supports interactive mode now, when you are prompted for password, please +input your password, and take care the wallet password which is different from accounts' +password. + +There are generally two steps to manage a BLS account: +1.Create a BLS wallet: geth bls wallet create +2.Create a BLS account: geth bls account new + or import a BLS account: geth bls account import `, + Subcommands: []cli.Command{ + { + Name: "wallet", + Usage: "Manage BLS wallet", + ArgsUsage: "", + Category: "BLS ACCOUNT COMMANDS", + Description: ` + +Create a BLS wallet to manage BLS accounts, this should before creating +or import a BLS account. The BLS wallet dir should be "/bls/wallet".`, + Subcommands: []cli.Command{ + { + Name: "create", + Usage: "Create BLS wallet", + Action: utils.MigrateFlags(blsWalletCreate), + ArgsUsage: "", + Category: "BLS ACCOUNT COMMANDS", + Flags: []cli.Flag{ + utils.DataDirFlag, + }, + Description: ` + geth bls wallet create + +will prompt for your password then create a BLS wallet in "/bls/wallet", +don't create BLS wallet repeatedly'.`, + }, + }, + }, + { + Name: "account", + Usage: "Manage BLS accounts", + ArgsUsage: "", + Category: "BLS ACCOUNT COMMANDS", + Description: ` + +Manage BLS accounts,list all existing accounts, import a BLS private key into +a new account, create a new account or delete an existing account. + +Make sure you remember the password you gave when creating a new account. +Without it you are not able to unlock your account. And this password is +different from the wallet password, please take care. + +Note that exporting your key in unencrypted format is NOT supported. + +Keys are stored under /bls/keystore. +It is safe to transfer the entire directory or the individual keys therein +between ethereum nodes by simply copying. + +Make sure you backup your BLS keys regularly.`, + Subcommands: []cli.Command{ + { + Name: "new", + Usage: "Create a BLS account", + Action: utils.MigrateFlags(blsAccountCreate), + ArgsUsage: "", + Category: "BLS ACCOUNT COMMANDS", + Flags: []cli.Flag{ + utils.DataDirFlag, + }, + Description: ` + geth bls account new + +Creates a new BLS account and imports the account into the BLS wallet. + +If the BLS wallet not created yet, it will try to create BLS wallet first. + +The account is saved in encrypted format, you are prompted for a password. +You must remember this password to unlock your account in the future.`, + }, + { + Name: "import", + Usage: "Import a BLS account", + Action: utils.MigrateFlags(blsAccountImport), + ArgsUsage: "", + Category: "BLS ACCOUNT COMMANDS", + Flags: []cli.Flag{ + utils.DataDirFlag, + }, + Description: ` + geth bls account import + +Import a encrypted BLS account from keystore file into the BLS wallet. + +If the BLS wallet not created yet, it will try to create BLS wallet first.`, + }, + { + Name: "list", + Usage: "Print summary of existing BLS accounts", + Action: utils.MigrateFlags(blsAccountList), + ArgsUsage: "", + Category: "BLS ACCOUNT COMMANDS", + Flags: []cli.Flag{ + utils.DataDirFlag, + }, + Description: ` + geth bls account list + +Print summary of existing BLS accounts in the current BLS wallet.`, + }, + { + Name: "delete", + Usage: "Delete the selected BLS account from the BLS wallet", + Action: utils.MigrateFlags(blsAccountDelete), + ArgsUsage: "", + Category: "BLS ACCOUNT COMMANDS", + Flags: []cli.Flag{ + utils.DataDirFlag, + }, + Description: ` + geth bls account delete + +Delete the selected BLS account from the BLS wallet.`, + }, + }, + }, + }, + } +) + +// blsWalletCreate creates a BLS wallet in /bls/wallet. +func blsWalletCreate(ctx *cli.Context) error { + cfg := gethConfig{Node: defaultNodeConfig()} + // Load config file. + if file := ctx.GlobalString(configFileFlag.Name); file != "" { + if err := loadConfig(file, &cfg); err != nil { + utils.Fatalf("%v", err) + } + } + utils.SetNodeConfig(ctx, &cfg.Node) + + dir := filepath.Join(cfg.Node.DataDir, BLSWalletPath) + dirExists, err := wallet.Exists(dir) + if err != nil { + utils.Fatalf("Check BLS wallet exists error: %v.", err) + } + if dirExists { + utils.Fatalf("BLS wallet already exists in /bls/wallet.") + } + + password := utils.GetPassPhrase("Your new BLS wallet will be locked with a password. Please give a password. Do not forget this password.", true) + + opts := []accounts.Option{} + opts = append(opts, accounts.WithWalletDir(dir)) + opts = append(opts, accounts.WithWalletPassword(password)) + opts = append(opts, accounts.WithKeymanagerType(keymanager.Local)) + opts = append(opts, accounts.WithSkipMnemonicConfirm(true)) + acc, err := accounts.NewCLIManager(opts...) + if err != nil { + utils.Fatalf("New Accounts CLI Manager failed: %v.", err) + } + if _, err := acc.WalletCreate(context.Background()); err != nil { + utils.Fatalf("Create BLS wallet failed: %v.", err) + } + + fmt.Println("Create BLS wallet successfully!") + return nil +} + +// openOrCreateBLSWallet opens BLS wallet in /bls/wallet, if wallet +// not exists, then creates BLS wallet in /bls/wallet. +func openOrCreateBLSWallet(ctx *cli.Context, cfg *gethConfig) (*wallet.Wallet, error) { + var w *wallet.Wallet + walletDir := filepath.Join(cfg.Node.DataDir, BLSWalletPath) + dirExists, err := wallet.Exists(walletDir) + if err != nil { + utils.Fatalf("Check dir %s failed: %v.", walletDir, err) + } + if !dirExists { + fmt.Println("BLS wallet not exists, creating BLS wallet...") + password := utils.GetPassPhrase("Your new BLS wallet will be locked with a password. Please give a password. Do not forget this password.", true) + + opts := []accounts.Option{} + opts = append(opts, accounts.WithWalletDir(walletDir)) + opts = append(opts, accounts.WithWalletPassword(password)) + opts = append(opts, accounts.WithKeymanagerType(keymanager.Local)) + opts = append(opts, accounts.WithSkipMnemonicConfirm(true)) + acc, err := accounts.NewCLIManager(opts...) + if err != nil { + utils.Fatalf("New Accounts CLI Manager failed: %v.", err) + } + w, err := acc.WalletCreate(context.Background()) + if err != nil { + utils.Fatalf("Create BLS wallet failed: %v.", err) + } + + fmt.Println("Create BLS wallet successfully!") + return w, nil + } + + walletPassword := utils.GetPassPhrase("Enter the password for your BLS wallet.", false) + w, err = wallet.OpenWallet(context.Background(), &wallet.Config{ + WalletDir: walletDir, + WalletPassword: walletPassword, + }) + if err != nil { + utils.Fatalf("Open BLS wallet failed: %v.", err) + } + return w, nil +} + +// blsAccountCreate creates a BLS account in /bls/keystore, +// and import the created account into the BLS wallet. +func blsAccountCreate(ctx *cli.Context) error { + cfg := gethConfig{Node: defaultNodeConfig()} + // Load config file. + if file := ctx.GlobalString(configFileFlag.Name); file != "" { + if err := loadConfig(file, &cfg); err != nil { + utils.Fatalf("%v", err) + } + } + utils.SetNodeConfig(ctx, &cfg.Node) + + w, _ := openOrCreateBLSWallet(ctx, &cfg) + if w.KeymanagerKind() != keymanager.Local { + utils.Fatalf("BLS wallet has wrong key manager kind.") + } + km, err := w.InitializeKeymanager(context.Background(), iface.InitKeymanagerConfig{ListenForChanges: false}) + if err != nil { + utils.Fatalf("Initialize key manager failed: %v.", err) + } + k, ok := km.(keymanager.Importer) + if !ok { + utils.Fatalf("The BLS keymanager cannot import keystores") + } + + keystoreDir := filepath.Join(cfg.Node.DataDir, BLSKeystorePath) + if err := os.MkdirAll(keystoreDir, 0755); err != nil { + utils.Fatalf("Could not access keystore dir: %v.", err) + } + accountPassword := utils.GetPassPhrase("Your new BLS account will be encrypted with a password. Please give a password. Do not forget this password.", true) + if err := core.ValidatePasswordFormat(accountPassword); err != nil { + utils.Fatalf("Password invalid: %v.", err) + } + + encryptor := keystorev4.New() + secretKey, err := bls.RandKey() + if err != nil { + utils.Fatalf("Could not generate BLS secret key: %v.", err) + } + pubKeyBytes := secretKey.PublicKey().Marshal() + cryptoFields, err := encryptor.Encrypt(secretKey.Marshal(), accountPassword) + if err != nil { + utils.Fatalf("Could not encrypt secret key: %v.", err) + } + id, err := uuid.NewRandom() + if err != nil { + utils.Fatalf("Could not generate uuid: %v.", err) + } + keystore := &keymanager.Keystore{ + Crypto: cryptoFields, + ID: id.String(), + Pubkey: fmt.Sprintf("%x", pubKeyBytes), + Version: encryptor.Version(), + Name: encryptor.Name(), + } + + encodedFile, err := json.MarshalIndent(keystore, "", "\t") + if err != nil { + utils.Fatalf("Could not marshal keystore to JSON file: %v.", err) + } + keystoreFile, err := os.Create(fmt.Sprintf("%s/keystore-%s.json", keystoreDir, petnames.DeterministicName(pubKeyBytes, "-"))) + if err != nil { + utils.Fatalf("Could not create keystore file: %v.", err) + } + if _, err := keystoreFile.Write(encodedFile); err != nil { + utils.Fatalf("Could not write keystore file contents: %v.", err) + } + fmt.Println("Successfully create a BLS account.") + + fmt.Println("Importing BLS account, this may take a while...") + _, err = accounts.ImportAccounts(context.Background(), &accounts.ImportAccountsConfig{ + Importer: k, + Keystores: []*keymanager.Keystore{keystore}, + AccountPassword: accountPassword, + }) + if err != nil { + utils.Fatalf("Import BLS account failed: %v.", err) + } + fmt.Printf("Successfully import created BLS account.\n") + return nil +} + +// blsAccountImport imports a BLS account into the BLS wallet. +func blsAccountImport(ctx *cli.Context) error { + keyfile := ctx.Args().First() + if len(keyfile) == 0 { + utils.Fatalf("The keystore file must be given as argument.") + } + keyJSON, err := ioutil.ReadFile(keyfile) + if err != nil { + utils.Fatalf("Could not read keystore file: %v", err) + } + keystore := &keymanager.Keystore{} + if err := json.Unmarshal(keyJSON, keystore); err != nil { + utils.Fatalf("Could not decode keystore file: %v.", err) + } + if keystore.Pubkey == "" { + utils.Fatalf(" Missing public key, wrong keystore file.") + } + + cfg := gethConfig{Node: defaultNodeConfig()} + // Load config file. + if file := ctx.GlobalString(configFileFlag.Name); file != "" { + if err := loadConfig(file, &cfg); err != nil { + utils.Fatalf("%v", err) + } + } + utils.SetNodeConfig(ctx, &cfg.Node) + + w, _ := openOrCreateBLSWallet(ctx, &cfg) + if w.KeymanagerKind() != keymanager.Local { + utils.Fatalf("BLS wallet has wrong key manager kind.") + } + km, err := w.InitializeKeymanager(context.Background(), iface.InitKeymanagerConfig{ListenForChanges: false}) + if err != nil { + utils.Fatalf("Initialize key manager failed: %v.", err) + } + k, ok := km.(keymanager.Importer) + if !ok { + utils.Fatalf("The BLS keymanager cannot import keystores") + } + + password := utils.GetPassPhrase("Enter the password for your imported account.", false) + fmt.Println("Importing BLS account, this may take a while...") + statuses, err := accounts.ImportAccounts(context.Background(), &accounts.ImportAccountsConfig{ + Importer: k, + Keystores: []*keymanager.Keystore{keystore}, + AccountPassword: password, + }) + if err != nil { + utils.Fatalf("Import BLS account failed: %v.", err) + } + // len(statuses)==len(Keystores) when err==nil + if statuses[0].Status == service.ImportedKeystoreStatus_ERROR { + fmt.Printf("Could not import keystore: %v.", statuses[0].Message) + } else { + fmt.Println("Successfully import BLS account.") + } + return nil +} + +// blsAccountList prints existing BLS accounts in the BLS wallet. +func blsAccountList(ctx *cli.Context) error { + cfg := gethConfig{Node: defaultNodeConfig()} + // Load config file. + if file := ctx.GlobalString(configFileFlag.Name); file != "" { + if err := loadConfig(file, &cfg); err != nil { + utils.Fatalf("%v", err) + } + } + utils.SetNodeConfig(ctx, &cfg.Node) + + walletDir := filepath.Join(cfg.Node.DataDir, BLSWalletPath) + dirExists, err := wallet.Exists(walletDir) + if err != nil || !dirExists { + utils.Fatalf("BLS wallet not exists.") + } + + walletPassword := utils.GetPassPhrase("Enter the password for your BLS wallet.", false) + w, err := wallet.OpenWallet(context.Background(), &wallet.Config{ + WalletDir: walletDir, + WalletPassword: walletPassword, + }) + if err != nil { + utils.Fatalf("Open BLS wallet failed: %v.", err) + } + km, err := w.InitializeKeymanager(context.Background(), iface.InitKeymanagerConfig{ListenForChanges: false}) + if err != nil { + utils.Fatalf("Initialize key manager failed: %v.", err) + } + + ikm, ok := km.(*local.Keymanager) + if !ok { + utils.Fatalf("Could not assert keymanager interface to concrete type.") + } + accountNames, err := ikm.ValidatingAccountNames() + if err != nil { + utils.Fatalf("Could not fetch account names: %v.", err) + } + numAccounts := au.BrightYellow(len(accountNames)) + fmt.Printf("(keymanager kind) %s\n", au.BrightGreen("imported wallet").Bold()) + fmt.Println("") + if len(accountNames) == 1 { + fmt.Printf("Showing %d BLS account\n", numAccounts) + } else { + fmt.Printf("Showing %d BLS accounts\n", numAccounts) + } + pubKeys, err := km.FetchValidatingPublicKeys(context.Background()) + if err != nil { + utils.Fatalf("Could not fetch BLS public keys: %v.", err) + } + for i := 0; i < len(accountNames); i++ { + fmt.Println("") + fmt.Printf("%s | %s\n", au.BrightBlue(fmt.Sprintf("Account %d", i)).Bold(), au.BrightGreen(accountNames[i]).Bold()) + fmt.Printf("%s %#x\n", au.BrightMagenta("[BLS public key]").Bold(), pubKeys[i]) + } + fmt.Println("") + return nil +} + +// blsAccountDelete deletes a selected BLS account from the BLS wallet. +func blsAccountDelete(ctx *cli.Context) error { + if len(ctx.Args()) == 0 { + utils.Fatalf("No BLS account specified to delete.") + } + var filteredPubKeys []bls.PublicKey + for _, str := range ctx.Args() { + pkString := str + if strings.Contains(pkString, "0x") { + pkString = pkString[2:] + } + pubKeyBytes, err := hex.DecodeString(pkString) + if err != nil { + utils.Fatalf("Could not decode string %s as hex.", pkString) + } + blsPublicKey, err := bls.PublicKeyFromBytes(pubKeyBytes) + if err != nil { + utils.Fatalf("%#x is not a valid BLS public key.", pubKeyBytes) + } + filteredPubKeys = append(filteredPubKeys, blsPublicKey) + } + + cfg := gethConfig{Node: defaultNodeConfig()} + // Load config file. + if file := ctx.GlobalString(configFileFlag.Name); file != "" { + if err := loadConfig(file, &cfg); err != nil { + utils.Fatalf("%v", err) + } + } + utils.SetNodeConfig(ctx, &cfg.Node) + + walletDir := filepath.Join(cfg.Node.DataDir, BLSWalletPath) + dirExists, err := wallet.Exists(walletDir) + if err != nil || !dirExists { + utils.Fatalf("BLS wallet not exists.") + } + + walletPassword := utils.GetPassPhrase("Enter the password for your BLS wallet.", false) + w, err := wallet.OpenWallet(context.Background(), &wallet.Config{ + WalletDir: walletDir, + WalletPassword: walletPassword, + }) + if err != nil { + utils.Fatalf("Open BLS wallet failed: %v.", err) + } + km, err := w.InitializeKeymanager(context.Background(), iface.InitKeymanagerConfig{ListenForChanges: false}) + if err != nil { + utils.Fatalf("Initialize key manager failed: %v.", err) + } + pubkeys, err := km.FetchValidatingPublicKeys(context.Background()) + if err != nil { + utils.Fatalf("Could not fetch BLS public keys: %v.", err) + } + + rawPublicKeys := make([][]byte, len(filteredPubKeys)) + formattedPubKeys := make([]string, len(filteredPubKeys)) + for i, pk := range filteredPubKeys { + pubKeyBytes := pk.Marshal() + rawPublicKeys[i] = pubKeyBytes + formattedPubKeys[i] = fmt.Sprintf("%#x", bytesutil.Trunc(pubKeyBytes)) + } + allAccountStr := strings.Join(formattedPubKeys, ", ") + if len(filteredPubKeys) == 1 { + promptText := "Are you sure you want to delete 1 account? (%s) Y/N" + resp, err := prompt.ValidatePrompt( + os.Stdin, fmt.Sprintf(promptText, au.BrightGreen(formattedPubKeys[0])), prompt.ValidateYesOrNo, + ) + if err != nil { + return err + } + if strings.EqualFold(resp, "n") { + return nil + } + } else { + promptText := "Are you sure you want to delete %d accounts? (%s) Y/N" + if len(filteredPubKeys) == len(pubkeys) { + promptText = fmt.Sprintf("Are you sure you want to delete all accounts? Y/N (%s)", au.BrightGreen(allAccountStr)) + } else { + promptText = fmt.Sprintf(promptText, len(filteredPubKeys), au.BrightGreen(allAccountStr)) + } + resp, err := prompt.ValidatePrompt(os.Stdin, promptText, prompt.ValidateYesOrNo) + if err != nil { + return err + } + if strings.EqualFold(resp, "n") { + return nil + } + } + + if err := accounts.DeleteAccount(context.Background(), &accounts.DeleteConfig{ + Keymanager: km, + DeletePublicKeys: rawPublicKeys, + }); err != nil { + utils.Fatalf("Delete account failed: %v.", err) + } + + return nil +} diff --git a/cmd/geth/main.go b/cmd/geth/main.go index 6ea505b503..6c08754809 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -72,6 +72,7 @@ var ( utils.DisableSnapProtocolFlag, utils.DisableDiffProtocolFlag, utils.EnableTrustProtocolFlag, + utils.DisableBscProtocolFlag, utils.DiffSyncFlag, utils.PipeCommitFlag, utils.RangeLimitFlag, @@ -168,6 +169,10 @@ var ( utils.BlockAmountReserved, utils.CheckSnapshotWithMPT, utils.EnableDoubleSignMonitorFlag, + utils.VotingEnabledFlag, + utils.BLSPasswordFileFlag, + utils.BLSWalletDirFlag, + utils.VoteJournalDirFlag, } rpcFlags = []cli.Flag{ @@ -251,6 +256,7 @@ func init() { utils.ShowDeprecated, // See snapshot.go snapshotCommand, + blsCommand, } sort.Sort(cli.CommandsByName(app.Commands)) diff --git a/cmd/geth/usage.go b/cmd/geth/usage.go index 5054067909..ab813a92f9 100644 --- a/cmd/geth/usage.go +++ b/cmd/geth/usage.go @@ -43,6 +43,7 @@ var AppHelpFlagGroups = []flags.FlagGroup{ utils.DisableSnapProtocolFlag, utils.DisableDiffProtocolFlag, utils.EnableTrustProtocolFlag, + utils.DisableBscProtocolFlag, utils.RangeLimitFlag, utils.SmartCardDaemonPathFlag, utils.NetworkIdFlag, @@ -59,6 +60,9 @@ var AppHelpFlagGroups = []flags.FlagGroup{ utils.TriesInMemoryFlag, utils.BlockAmountReserved, utils.CheckSnapshotWithMPT, + utils.BLSPasswordFileFlag, + utils.BLSWalletDirFlag, + utils.VoteJournalDirFlag, }, }, { @@ -195,6 +199,7 @@ var AppHelpFlagGroups = []flags.FlagGroup{ utils.MinerRecommitIntervalFlag, utils.MinerDelayLeftoverFlag, utils.MinerNoVerfiyFlag, + utils.VotingEnabledFlag, }, }, { @@ -237,6 +242,12 @@ var AppHelpFlagGroups = []flags.FlagGroup{ cli.HelpFlag, }, }, + { + Name: "BLS ACCOUNT", + Flags: []cli.Flag{ + utils.DataDirFlag, + }, + }, } func init() { diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 9f4e4b6d10..7a73a0a988 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -25,6 +25,7 @@ import ( "math" "math/big" "os" + "path/filepath" "runtime" godebug "runtime/debug" "strconv" @@ -133,10 +134,14 @@ var ( Name: "enabletrustprotocol", Usage: "Enable trust protocol", } + DisableBscProtocolFlag = cli.BoolFlag{ + Name: "disablebscprotocol", + Usage: "Disable bsc protocol", + } + DiffSyncFlag = cli.BoolFlag{ - Name: "diffsync", - Usage: "Enable diffy sync, Please note that enable diffsync will improve the syncing speed, " + - "but will degrade the security to light client level", + Name: "diffsync", + Usage: "warn: diff sync has been deprecated, the flag will be removed in the future", } PipeCommitFlag = cli.BoolFlag{ Name: "pipecommit", @@ -890,6 +895,26 @@ var ( Name: "monitor.doublesign", Usage: "Enable double sign monitor to check whether any validator signs multiple blocks", } + + VotingEnabledFlag = cli.BoolFlag{ + Name: "vote", + Usage: "Enable voting", + } + + BLSPasswordFileFlag = cli.StringFlag{ + Name: "blspassword", + Usage: "File path for the BLS password, which contains the password to unlock BLS wallet for managing votes in fast_finality feature", + } + + BLSWalletDirFlag = DirectoryFlag{ + Name: "blswallet", + Usage: "Path for the blsWallet dir in fast finality feature (default = inside the datadir)", + } + + VoteJournalDirFlag = DirectoryFlag{ + Name: "vote-journal-path", + Usage: "Path for the voteJournal dir in fast finality feature (default = inside the datadir)", + } ) // MakeDataDir retrieves the currently requested data directory, terminating @@ -1305,6 +1330,8 @@ func SetNodeConfig(ctx *cli.Context, cfg *node.Config) { setDataDir(ctx, cfg) setSmartCard(ctx, cfg) setMonitor(ctx, cfg) + setBLSWalletDir(ctx, cfg) + setVoteJournalDir(ctx, cfg) if ctx.GlobalIsSet(ExternalSignerFlag.Name) { cfg.ExternalSigner = ctx.GlobalString(ExternalSignerFlag.Name) @@ -1337,6 +1364,10 @@ func SetNodeConfig(ctx *cli.Context, cfg *node.Config) { if ctx.GlobalIsSet(InsecureUnlockAllowedFlag.Name) { cfg.InsecureUnlockAllowed = ctx.GlobalBool(InsecureUnlockAllowedFlag.Name) } + + if ctx.GlobalIsSet(BLSPasswordFileFlag.Name) { + cfg.BLSPasswordFile = ctx.GlobalString(BLSPasswordFileFlag.Name) + } } func setSmartCard(ctx *cli.Context, cfg *node.Config) { @@ -1368,6 +1399,24 @@ func setDataDir(ctx *cli.Context, cfg *node.Config) { } } +func setVoteJournalDir(ctx *cli.Context, cfg *node.Config) { + dataDir := cfg.DataDir + if ctx.GlobalIsSet(VoteJournalDirFlag.Name) { + cfg.VoteJournalDir = ctx.GlobalString(VoteJournalDirFlag.Name) + } else { + cfg.VoteJournalDir = filepath.Join(dataDir, "voteJournal") + } +} + +func setBLSWalletDir(ctx *cli.Context, cfg *node.Config) { + dataDir := cfg.DataDir + if ctx.GlobalIsSet(BLSWalletDirFlag.Name) { + cfg.BLSWalletDir = ctx.GlobalString(BLSWalletDirFlag.Name) + } else { + cfg.BLSWalletDir = filepath.Join(dataDir, "bls/wallet") + } +} + func setGPO(ctx *cli.Context, cfg *gasprice.Config, light bool) { // If we are running the light client, apply another group // settings for gas oracle. @@ -1487,6 +1536,9 @@ func setMiner(ctx *cli.Context, cfg *miner.Config) { if ctx.GlobalIsSet(LegacyMinerGasTargetFlag.Name) { log.Warn("The generic --miner.gastarget flag is deprecated and will be removed in the future!") } + if ctx.GlobalBool(VotingEnabledFlag.Name) { + cfg.VoteEnable = true + } } func setWhitelist(ctx *cli.Context, cfg *ethconfig.Config) { @@ -1645,6 +1697,9 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) { if ctx.GlobalIsSet(EnableTrustProtocolFlag.Name) { cfg.EnableTrustProtocol = ctx.GlobalIsSet(EnableTrustProtocolFlag.Name) } + if ctx.GlobalIsSet(DisableBscProtocolFlag.Name) { + cfg.DisableBscProtocol = ctx.GlobalIsSet(DisableBscProtocolFlag.Name) + } if ctx.GlobalIsSet(DiffSyncFlag.Name) { log.Warn("The --diffsync flag is deprecated and will be removed in the future!") } @@ -1721,7 +1776,7 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) { cfg.RPCTxFeeCap = ctx.GlobalFloat64(RPCGlobalTxFeeCapFlag.Name) } if ctx.GlobalIsSet(NoDiscoverFlag.Name) { - cfg.EthDiscoveryURLs, cfg.SnapDiscoveryURLs, cfg.TrustDiscoveryURLs = []string{}, []string{}, []string{} + cfg.EthDiscoveryURLs, cfg.SnapDiscoveryURLs, cfg.TrustDiscoveryURLs, cfg.BscDiscoveryURLs = []string{}, []string{}, []string{}, []string{} } else if ctx.GlobalIsSet(DNSDiscoveryFlag.Name) { urls := ctx.GlobalString(DNSDiscoveryFlag.Name) if urls == "" { @@ -1812,6 +1867,7 @@ func SetDNSDiscoveryDefaults(cfg *ethconfig.Config, genesis common.Hash) { cfg.EthDiscoveryURLs = []string{url} cfg.SnapDiscoveryURLs = cfg.EthDiscoveryURLs cfg.TrustDiscoveryURLs = cfg.EthDiscoveryURLs + cfg.BscDiscoveryURLs = cfg.EthDiscoveryURLs } } diff --git a/common/math/integer.go b/common/math/integer.go index 50d3eba1f5..36643b5bca 100644 --- a/common/math/integer.go +++ b/common/math/integer.go @@ -96,3 +96,10 @@ func SafeMul(x, y uint64) (uint64, bool) { hi, lo := bits.Mul64(x, y) return lo, hi != 0 } + +func CeilDiv(x, y int) int { + if y == 0 { + return 0 + } + return (x + y - 1) / y +} diff --git a/consensus/consensus.go b/consensus/consensus.go index 87632a9d0d..30c4559043 100644 --- a/consensus/consensus.go +++ b/consensus/consensus.go @@ -57,6 +57,10 @@ type ChainHeaderReader interface { GetHighestVerifiedHeader() *types.Header } +type VotePool interface { + FetchVoteByBlockHash(blockHash common.Hash) []*types.VoteEnvelope +} + // ChainReader defines a small collection of methods needed to access the local // blockchain during header and/or uncle verification. type ChainReader interface { @@ -148,4 +152,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, common.Hash, error) + GetFinalizedHeader(chain ChainHeaderReader, header *types.Header) *types.Header + VerifyVote(chain ChainHeaderReader, vote *types.VoteEnvelope) error + IsActiveValidatorAt(chain ChainHeaderReader, header *types.Header) bool } diff --git a/consensus/parlia/abi.go b/consensus/parlia/abi.go index e841eb5cd5..ffe97a45ce 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 0000000000..6ce14364c4 --- /dev/null +++ b/consensus/parlia/lubanFork.go @@ -0,0 +1,49 @@ +package parlia + +import ( + "context" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/common/math" + "github.com/ethereum/go-ethereum/core/systemcontracts" + "github.com/ethereum/go-ethereum/internal/ethapi" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/rpc" +) + +func (p *Parlia) getCurrentValidatorsBeforeLuban(blockHash common.Hash, blockNumber *big.Int) ([]common.Address, error) { + blockNr := rpc.BlockNumberOrHashWithHash(blockHash, false) + + // prepare different method + method := "getValidators" + if p.chainConfig.IsEuler(blockNumber) { + method = "getMiningValidators" + } + + ctx, cancel := context.WithCancel(context.Background()) + // cancel when we are finished consuming integers + defer cancel() + 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 := (hexutil.Bytes)(data) + toAddress := common.HexToAddress(systemcontracts.ValidatorContract) + gas := (hexutil.Uint64)(uint64(math.MaxUint64 / 2)) + result, err := p.ethAPI.Call(ctx, ethapi.TransactionArgs{ + Gas: &gas, + To: &toAddress, + Data: &msgData, + }, blockNr, nil) + if err != nil { + return nil, err + } + + var valSet []common.Address + err = p.validatorSetABIBeforeLuban.UnpackIntoInterface(&valSet, method, result) + return valSet, err +} diff --git a/consensus/parlia/parlia.go b/consensus/parlia/parlia.go index b1abc1221f..a1eaf83a30 100644 --- a/consensus/parlia/parlia.go +++ b/consensus/parlia/parlia.go @@ -16,6 +16,8 @@ import ( "time" lru "github.com/hashicorp/golang-lru" + "github.com/prysmaticlabs/prysm/v3/crypto/bls" + "github.com/willf/bitset" "golang.org/x/crypto/sha3" "github.com/ethereum/go-ethereum" @@ -24,6 +26,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/gopool" "github.com/ethereum/go-ethereum/common/hexutil" + cmath "github.com/ethereum/go-ethereum/common/math" "github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/consensus/misc" "github.com/ethereum/go-ethereum/core" @@ -36,6 +39,7 @@ import ( "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/internal/ethapi" "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/metrics" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rpc" @@ -53,13 +57,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 = common.AddressLength - wiggleTime = uint64(1) // second, Random delay (per signer) to allow concurrent signers - initialBackOffTime = uint64(1) // second - processBackOffTime = uint64(1) // second + validatorBytesLengthBeforeLuban = common.AddressLength + validatorBytesLength = common.AddressLength + types.BLSPublicKeyLength + validatorNumberSize = 1 // Fixed number of extra prefix bytes reserved for validator number after Luban + + wiggleTime = uint64(1) // second, Random delay (per signer) to allow concurrent signers + initialBackOffTime = uint64(1) // second + 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 ( @@ -67,7 +75,9 @@ var ( diffInTurn = big.NewInt(2) // Block difficulty for in-turn signatures diffNoTurn = big.NewInt(1) // Block difficulty for out-of-turn signatures // 100 native token - maxSystemBalance = new(big.Int).Mul(big.NewInt(100), big.NewInt(params.Ether)) + maxSystemBalance = new(big.Int).Mul(big.NewInt(100), big.NewInt(params.Ether)) + verifyVoteAttestationFailedGauge = metrics.NewRegisteredGauge("parlia/verifyVoteAttestationFailed", nil) + updateAttestationFailedGauge = metrics.NewRegisteredGauge("parlia/updateAttestationFailed", nil) systemContracts = map[common.Address]bool{ common.HexToAddress(systemcontracts.ValidatorContract): true, @@ -208,9 +218,11 @@ type Parlia struct { lock sync.RWMutex // Protects the signer fields - ethAPI *ethapi.PublicBlockChainAPI - validatorSetABI abi.ABI - slashABI abi.ABI + ethAPI *ethapi.PublicBlockChainAPI + VotePool consensus.VotePool + validatorSetABIBeforeLuban abi.ABI + validatorSetABI abi.ABI + slashABI abi.ABI // The fields below are for testing only fakeDiff bool // Skip difficulty verifications @@ -240,6 +252,10 @@ func New( if err != nil { panic(err) } + vABIBeforeLuban, err := abi.JSON(strings.NewReader(validatorSetABIBeforeLuban)) + if err != nil { + panic(err) + } vABI, err := abi.JSON(strings.NewReader(validatorSetABI)) if err != nil { panic(err) @@ -249,16 +265,17 @@ func New( panic(err) } c := &Parlia{ - chainConfig: chainConfig, - config: parliaConfig, - genesisHash: genesisHash, - db: db, - ethAPI: ethAPI, - recentSnaps: recentSnaps, - signatures: signatures, - validatorSetABI: vABI, - slashABI: sABI, - signer: types.NewEIP155Signer(chainConfig.ChainID), + chainConfig: chainConfig, + config: parliaConfig, + genesisHash: genesisHash, + db: db, + ethAPI: ethAPI, + recentSnaps: recentSnaps, + signatures: signatures, + validatorSetABIBeforeLuban: vABIBeforeLuban, + validatorSetABI: vABI, + slashABI: sABI, + signer: types.NewEIP155Signer(chainConfig.ChainID), } return c @@ -317,6 +334,160 @@ func (p *Parlia) VerifyHeaders(chain consensus.ChainHeaderReader, headers []*typ return abort, results } +// 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 *params.ChainConfig, parliaConfig *params.ParliaConfig) []byte { + if len(header.Extra) <= extraVanity+extraSeal { + return nil + } + + if !chainConfig.IsLuban(header.Number) { + if header.Number.Uint64()%parliaConfig.Epoch == 0 && (len(header.Extra)-extraSeal-extraVanity)%validatorBytesLengthBeforeLuban != 0 { + 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 *params.ChainConfig, parliaConfig *params.ParliaConfig) (*types.VoteAttestation, error) { + if len(header.Extra) <= extraVanity+extraSeal { + return nil, nil + } + + if !chainConfig.IsLuban(header.Number) { + 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) + 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) < cmath.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 @@ -325,7 +496,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()) { @@ -338,16 +508,17 @@ 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 } @@ -426,11 +597,24 @@ 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 { + verifyVoteAttestationFailedGauge.Inc(1) + if chain.Config().IsPlato(header.Number) { + 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) } // 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 common.Hash, parents []*types.Header) (*Snapshot, error) { // Search for a snapshot in memory or on disk for checkpoints var ( @@ -454,25 +638,23 @@ func (p *Parlia) snapshot(chain consensus.ChainHeaderReader, number uint64, hash } } - // If we're at the genesis, snapshot the initial state. - if number == 0 { + // If we're at the genesis, snapshot the initial state. Alternatively if we have + // piled up more headers than allowed to be reorged (chain reinit from a freezer), + // consider the checkpoint trusted and snapshot it. + if number == 0 || (number%p.config.Epoch == 0 && (len(headers) > params.FullImmutabilityThreshold)) { checkpoint := chain.GetHeaderByNumber(number) if checkpoint != nil { // get checkpoint data hash := checkpoint.Hash() - if len(checkpoint.Extra) <= extraVanity+extraSeal { - return nil, errors.New("invalid extra-data for genesis block, check the genesis.json file") - } - 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 snap shot - snap = newSnapshot(p.config, p.signatures, number, hash, validators, p.ethAPI) + // new snapshot + snap = newSnapshot(p.config, p.signatures, number, hash, validators, voteAddrs, p.ethAPI) if err := snap.store(p.db); err != nil { return nil, err } @@ -511,7 +693,7 @@ func (p *Parlia) snapshot(chain consensus.ChainHeaderReader, number uint64, hash headers[i], headers[len(headers)-1-i] = headers[len(headers)-1-i], headers[i] } - snap, err := snap.apply(headers, chain, parents, p.chainConfig.ChainID) + snap, err := snap.apply(headers, chain, parents, p.chainConfig) if err != nil { return nil, err } @@ -595,6 +777,109 @@ func (p *Parlia) verifySeal(chain consensus.ChainHeaderReader, header *types.Hea return nil } +func (p *Parlia) prepareValidators(header *types.Header) error { + if header.Number.Uint64()%p.config.Epoch != 0 { + return nil + } + + newValidators, voteAddressMap, err := p.getCurrentValidators(header.ParentHash, new(big.Int).Sub(header.Number, big.NewInt(1))) + if err != nil { + return err + } + // sort validator by address + sort.Sort(validatorsAscending(newValidators)) + if !p.chainConfig.IsLuban(header.Number) { + 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 +} + +func (p *Parlia) assembleVoteAttestation(chain consensus.ChainHeaderReader, header *types.Header) error { + if !p.chainConfig.IsLuban(header.Number) || header.Number.Uint64() < 2 { + return nil + } + + if p.VotePool == nil { + return errors.New("vote pool is nil") + } + + // Fetch direct parent's votes + parent := chain.GetHeaderByHash(header.ParentHash) + if parent == nil { + return errors.New("parent not found") + } + snap, err := p.snapshot(chain, parent.Number.Uint64()-1, parent.ParentHash, nil) + if err != nil { + return err + } + votes := p.VotePool.FetchVoteByBlockHash(parent.Hash()) + if len(votes) < cmath.CeilDiv(len(snap.Validators)*2, 3) { + return nil + } + + // Prepare vote attestation + // Prepare vote data + justifiedBlockNumber, justifiedBlockHash, err := p.GetJustifiedNumberAndHash(chain, parent) + if err != nil { + return fmt.Errorf("unexpected error when getting the highest justified number and hash") + } + attestation := &types.VoteAttestation{ + Data: &types.VoteData{ + SourceNumber: justifiedBlockNumber, + SourceHash: justifiedBlockHash, + TargetNumber: parent.Number.Uint64(), + TargetHash: parent.Hash(), + }, + } + // Check vote data from votes + for _, vote := range votes { + if vote.Data.Hash() != attestation.Data.Hash() { + return fmt.Errorf("vote check error, expected: %v, real: %v", attestation.Data, vote) + } + } + // Prepare aggregated vote signature + voteAddrSet := make(map[types.BLSPublicKey]struct{}, len(votes)) + signatures := make([][]byte, 0, len(votes)) + for _, vote := range votes { + voteAddrSet[vote.VoteAddress] = struct{}{} + signatures = append(signatures, vote.Signature[:]) + } + sigs, err := bls.MultipleSignaturesFromBytes(signatures) + if err != nil { + return err + } + copy(attestation.AggSignature[:], bls.AggregateSignatures(sigs).Marshal()) + // Prepare vote address bitset. + for _, valInfo := range snap.Validators { + if _, ok := voteAddrSet[valInfo.VoteAddress]; ok { + attestation.VoteAddressSet |= 1 << (valInfo.Index - 1) //Index is offset by 1 + } + } + + // Append attestation to header extra field. + buf := new(bytes.Buffer) + err = rlp.Encode(buf, attestation) + if err != nil { + return err + } + + // Insert vote attestation into header extra ahead extra seal. + extraSealStart := len(header.Extra) - extraSeal + extraSealBytes := header.Extra[extraSealStart:] + header.Extra = append(header.Extra[0:extraSealStart], buf.Bytes()...) + header.Extra = append(header.Extra, extraSealBytes...) + + return nil +} + // Prepare implements consensus.Engine, preparing all the consensus fields of the // header for running the transactions on top. func (p *Parlia) Prepare(chain consensus.ChainHeaderReader, header *types.Header) error { @@ -618,16 +903,8 @@ func (p *Parlia) Prepare(chain consensus.ChainHeaderReader, header *types.Header nextForkHash := forkid.NextForkHash(p.chainConfig, p.genesisHash, number) header.Extra = append(header.Extra, nextForkHash[:]...) - if number%p.config.Epoch == 0 { - newValidators, err := p.getCurrentValidators(header.ParentHash, new(big.Int).Sub(header.Number, common.Big1)) - 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); err != nil { + return err } // add extra seal space @@ -648,6 +925,114 @@ func (p *Parlia) Prepare(chain consensus.ChainHeaderReader, header *types.Header return nil } +func (p *Parlia) verifyValidators(header *types.Header) error { + if header.Number.Uint64()%p.config.Epoch != 0 { + return nil + } + + newValidators, voteAddressMap, err := p.getCurrentValidators(header.ParentHash, new(big.Int).Sub(header.Number, big.NewInt(1))) + if err != nil { + return err + } + // sort validator by address + sort.Sort(validatorsAscending(newValidators)) + var validatorsBytes []byte + validatorsNumber := len(newValidators) + if !p.chainConfig.IsLuban(header.Number) { + 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+common.AddressLength:], voteAddressMap[validator].Bytes()) + } + } + if !bytes.Equal(getValidatorBytesFromHeader(header, p.chainConfig, p.config), validatorsBytes) { + return errMismatchingEpochValidators + } + return nil +} + +func (p *Parlia) distributeFinalityReward(chain consensus.ChainHeaderReader, state *state.StateDB, header *types.Header, + cx core.ChainContext, txs *[]*types.Transaction, receipts *[]*types.Receipt, systemTxs *[]*types.Transaction, + usedGas *uint64, mining bool) error { + currentHeight := header.Number.Uint64() + epoch := p.config.Epoch + chainConfig := chain.Config() + if currentHeight%epoch != 0 { + return nil + } + + head := header + accumulatedWeights := make(map[common.Address]uint64) + for height := currentHeight - 1; height+epoch >= currentHeight && height >= 1; height-- { + head = chain.GetHeaderByHash(head.ParentHash) + if head == nil { + return fmt.Errorf("header is nil at height %d", height) + } + voteAttestation, err := getVoteAttestationFromHeader(head, chainConfig, p.config) + if err != nil { + return 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) + if err != nil { + return 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 := cmath.CeilDiv(len(snap.Validators)*2, 3) + if validVoteCount > quorum { + accumulatedWeights[head.Coinbase] += uint64(float64(validVoteCount-quorum) * collectAdditionalVotesRewardRatio) + } + } + + validators := make([]common.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 err + } + msg := p.getSystemMessage(header.Coinbase, common.HexToAddress(systemcontracts.ValidatorContract), data, common.Big0) + return p.applyTransaction(msg, state, header, cx, txs, receipts, systemTxs, usedGas, mining) +} + // Finalize implements consensus.Engine, ensuring no uncles are set, nor block // rewards given. func (p *Parlia) Finalize(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs *[]*types.Transaction, @@ -662,27 +1047,15 @@ func (p *Parlia) Finalize(chain consensus.ChainHeaderReader, header *types.Heade if !snap.isMajorityFork(hex.EncodeToString(nextForkHash[:])) { log.Debug("there is a possible fork, and your client is not the majority. Please check...", "nextForkHash", hex.EncodeToString(nextForkHash[:])) } - // If the block is a epoch end block, verify the validator list + // 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 header.Number.Uint64()%p.config.Epoch == 0 { - newValidators, err := p.getCurrentValidators(header.ParentHash, new(big.Int).Sub(header.Number, common.Big1)) - if err != nil { - return 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 errMismatchingEpochValidators - } + if err := p.verifyValidators(header); err != nil { + return err } - // No block rewards in PoA, so the state remains as is and uncles are dropped + cx := chainContext{Chain: chain, parlia: p} + + // No block rewards in PoA, so the state remains as is and uncles are dropped if header.Number.Cmp(common.Big1) == 0 { err := p.initContract(state, header, cx, txs, receipts, systemTxs, usedGas, false) if err != nil { @@ -712,6 +1085,12 @@ func (p *Parlia) Finalize(chain consensus.ChainHeaderReader, header *types.Heade if err != nil { return err } + + if p.chainConfig.IsPlato(header.Number) { + if err := p.distributeFinalityReward(chain, state, header, cx, txs, receipts, systemTxs, usedGas, false); err != nil { + return err + } + } if len(*systemTxs) > 0 { return errors.New("the length of systemTxs do not match") } @@ -758,10 +1137,18 @@ func (p *Parlia) FinalizeAndAssemble(chain consensus.ChainHeaderReader, header * } } } + err := p.distributeIncoming(p.val, state, header, cx, &txs, &receipts, nil, &header.GasUsed, true) if err != nil { return nil, nil, err } + + if p.chainConfig.IsPlato(header.Number) { + if err := p.distributeFinalityReward(chain, state, header, cx, &txs, &receipts, nil, &header.GasUsed, true); err != nil { + return nil, nil, err + } + } + // should not happen. Once happen, stop the node is better than broadcast the block if header.GasLimit < header.GasUsed { return nil, nil, errors.New("gas consumption of system txs exceed the gas limit") @@ -785,6 +1172,59 @@ func (p *Parlia) FinalizeAndAssemble(chain consensus.ChainHeaderReader, header * return blk, receipts, nil } +func (p *Parlia) IsActiveValidatorAt(chain consensus.ChainHeaderReader, header *types.Header) bool { + number := header.Number.Uint64() + snap, err := p.snapshot(chain, number-1, header.ParentHash, nil) + if err != nil { + log.Error("failed to get the snapshot from consensus", "error", err) + return false + } + validators := snap.Validators + _, ok := validators[p.val] + return ok +} + +// VerifyVote will verify: 1. If the vote comes from valid validators 2. If the vote's sourceNumber and sourceHash are correct +func (p *Parlia) VerifyVote(chain consensus.ChainHeaderReader, vote *types.VoteEnvelope) error { + targetNumber := vote.Data.TargetNumber + targetHash := vote.Data.TargetHash + header := chain.GetHeaderByHash(targetHash) + if header == nil { + log.Warn("BlockHeader at current voteBlockNumber is nil", "targetNumber", targetNumber, "targetHash", targetHash) + return fmt.Errorf("BlockHeader at current voteBlockNumber is nil") + } + if header.Number.Uint64() != targetNumber { + log.Warn("unexpected target number", "expect", header.Number.Uint64(), "real", targetNumber) + return fmt.Errorf("target number mismatch") + } + + justifiedBlockNumber, justifiedBlockHash, err := p.GetJustifiedNumberAndHash(chain, header) + if err != nil { + log.Error("failed to get the highest justified number and hash", "headerNumber", header.Number, "headerHash", header.Hash()) + return fmt.Errorf("unexpected error when getting the highest justified number and hash") + } + if vote.Data.SourceNumber != justifiedBlockNumber || vote.Data.SourceHash != justifiedBlockHash { + return fmt.Errorf("vote source block mismatch") + } + + number := header.Number.Uint64() + snap, err := p.snapshot(chain, number-1, header.ParentHash, nil) + if err != nil { + log.Error("failed to get the snapshot from consensus", "error", err) + return fmt.Errorf("failed to get the snapshot from consensus") + } + + validators := snap.Validators + voteAddress := vote.VoteAddress + for _, validator := range validators { + if validator.VoteAddress == voteAddress { + return nil + } + } + + return fmt.Errorf("vote verification failed") +} + // Authorize injects a private key into the consensus engine to mint new blocks // with. func (p *Parlia) Authorize(val common.Address, signFn SignerFn, signTxFn SignerTxFn) { @@ -869,13 +1309,6 @@ func (p *Parlia) Seal(chain consensus.ChainHeaderReader, block *types.Block, res log.Info("Sealing block with", "number", number, "delay", delay, "headerDifficulty", header.Difficulty, "val", val.Hex()) - // Sign all the things! - sig, err := signFn(accounts.Account{Address: val}, accounts.MimetypeParlia, ParliaRLP(header, p.chainConfig.ChainID)) - if err != nil { - return err - } - copy(header.Extra[len(header.Extra)-extraSeal:], sig) - // Wait until sealing is terminated or delay timeout. log.Trace("Waiting for slot to sign and propagate", "delay", common.PrettyDuration(delay)) go func() { @@ -884,6 +1317,22 @@ func (p *Parlia) Seal(chain consensus.ChainHeaderReader, block *types.Block, res return case <-time.After(delay): } + + err := p.assembleVoteAttestation(chain, header) + if err != nil { + /* If the vote attestation can't be assembled successfully, the blockchain won't get + fast finalized, but it can be tolerated, so just report this error here. */ + log.Error("Assemble vote attestation failed when sealing", "err", err) + } + + // Sign all the things! + sig, err := signFn(accounts.Account{Address: val}, accounts.MimetypeParlia, ParliaRLP(header, p.chainConfig.ChainID)) + if err != nil { + log.Error("Sign for the block header failed when sealing", "err", err) + return + } + copy(header.Extra[len(header.Extra)-extraSeal:], sig) + if p.shouldWaitForCurrentBlockProcess(chain, header, snap) { log.Info("Waiting for received in turn block to process") select { @@ -891,6 +1340,10 @@ func (p *Parlia) Seal(chain consensus.ChainHeaderReader, block *types.Block, res log.Info("Received block process finished, abort block seal") return case <-time.After(time.Duration(processBackOffTime) * time.Second): + if chain.CurrentHeader().Number.Uint64() >= header.Number.Uint64() { + log.Info("Process backoff time exhausted, and current header has updated to abort this seal") + return + } log.Info("Process backoff time exhausted, start to seal block") } } @@ -958,11 +1411,13 @@ func (p *Parlia) SignRecently(chain consensus.ChainReader, parent *types.Block) // If we're amongst the recent signers, wait for the next block number := parent.NumberU64() + 1 for seen, recent := range snap.Recents { - if recent == p.val { - // Signer is among recents, only wait if the current block doesn't shift it out - if limit := uint64(len(snap.Validators)/2 + 1); number < limit || seen > number-limit { - return true, nil - } + if recent != p.val { + continue + } + + // Signer is among recents, only wait if the current block doesn't shift it out + if limit := uint64(len(snap.Validators)/2 + 1); number < limit || seen > number-limit { + return true, nil } } return false, nil @@ -989,9 +1444,13 @@ func CalcDifficulty(snap *Snapshot, signer common.Address) *big.Int { return new(big.Int).Set(diffNoTurn) } -// SealHash returns the hash of a block prior to it being sealed. -func (p *Parlia) SealHash(header *types.Header) common.Hash { - return SealHash(header, p.chainConfig.ChainID) +// SealHash returns the hash of a block without vote attestation prior to it being sealed. +// So it's not the real hash of a block, just used as unique id to distinguish task +func (p *Parlia) SealHash(header *types.Header) (hash common.Hash) { + hasher := sha3.NewLegacyKeccak256() + encodeSigHeaderWithoutVoteAttestation(hasher, header, p.chainConfig.ChainID) + hasher.Sum(hash[:0]) + return hash } // APIs implements consensus.Engine, returning the user facing RPC API to query snapshot. @@ -1012,23 +1471,25 @@ func (p *Parlia) Close() error { // ========================== interaction with contract/account ========= // getCurrentValidators get current validators -func (p *Parlia) getCurrentValidators(blockHash common.Hash, blockNumber *big.Int) ([]common.Address, error) { +func (p *Parlia) getCurrentValidators(blockHash common.Hash, blockNum *big.Int) ([]common.Address, map[common.Address]*types.BLSPublicKey, error) { // block blockNr := rpc.BlockNumberOrHashWithHash(blockHash, false) - // method - method := "getValidators" - if p.chainConfig.IsEuler(blockNumber) { - method = "getMiningValidators" + if !p.chainConfig.IsLuban(blockNum) { + validators, err := p.getCurrentValidatorsBeforeLuban(blockHash, blockNum) + return validators, nil, err } + // method + method := "getMiningValidators" + ctx, cancel := context.WithCancel(context.Background()) defer cancel() // cancel when we are finished consuming integers data, err := p.validatorSetABI.Pack(method) if err != nil { - log.Error("Unable to pack tx for getValidators", "error", err) - return nil, err + log.Error("Unable to pack tx for getMiningValidators", "error", err) + return nil, nil, err } // call msgData := (hexutil.Bytes)(data) @@ -1040,24 +1501,21 @@ func (p *Parlia) getCurrentValidators(blockHash common.Hash, blockNumber *big.In Data: &msgData, }, blockNr, nil) if err != nil { - return nil, err + return nil, nil, err } - var ( - ret0 = new([]common.Address) - ) - out := ret0 + var valSet []common.Address + var voteAddrSet []types.BLSPublicKey - if err := p.validatorSetABI.UnpackIntoInterface(out, method, result); err != nil { - return nil, err + if err := p.validatorSetABI.UnpackIntoInterface(&[]interface{}{&valSet, &voteAddrSet}, method, result); err != nil { + return nil, nil, err } - valz := make([]common.Address, len(*ret0)) - // nolint: gosimple - for i, a := range *ret0 { - valz[i] = a + voteAddrmap := make(map[common.Address]*types.BLSPublicKey, len(valSet)) + for i := 0; i < len(valSet); i++ { + voteAddrmap[valSet[i]] = &(voteAddrSet)[i] } - return valz, nil + return valSet, voteAddrmap, nil } // slash spoiled validators @@ -1248,6 +1706,65 @@ func (p *Parlia) applyTransaction( return 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, common.Hash, error) { + if chain == nil || header == nil { + return 0, common.Hash{}, fmt.Errorf("illegal chain or header") + } + snap, err := p.snapshot(chain, header.Number.Uint64(), header.Hash(), nil) + if err != nil { + log.Error("Unexpected error when getting snapshot", + "error", err, "blockNumber", header.Number.Uint64(), "blockHash", header.Hash()) + return 0, common.Hash{}, err + } + + if snap.Attestation == nil { + if p.chainConfig.IsLuban(header.Number) { + 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) { + return chain.GetHeaderByNumber(0) + } + if header.Number.Uint64() < backward { + backward = header.Number.Uint64() + } + + snap, err := p.snapshot(chain, header.Number.Uint64(), header.Hash(), nil) + 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) + 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) +} + // =========================== utility function ========================== // SealHash returns the hash of a block prior to it being sealed. func SealHash(header *types.Header, chainId *big.Int) (hash common.Hash) { @@ -1281,6 +1798,30 @@ func encodeSigHeader(w io.Writer, header *types.Header, chainId *big.Int) { } } +func encodeSigHeaderWithoutVoteAttestation(w io.Writer, header *types.Header, chainId *big.Int) { + err := rlp.Encode(w, []interface{}{ + chainId, + header.ParentHash, + header.UncleHash, + header.Coinbase, + header.Root, + header.TxHash, + header.ReceiptHash, + header.Bloom, + header.Difficulty, + header.Number, + header.GasLimit, + header.GasUsed, + header.Time, + header.Extra[:extraVanity], // this will panic if extra is too short, should check before calling encodeSigHeaderWithoutVoteAttestation + header.MixDigest, + header.Nonce, + }) + if err != nil { + panic("can't encode: " + err.Error()) + } +} + func (p *Parlia) backOffTime(snap *Snapshot, header *types.Header, val common.Address) uint64 { if snap.inturn(val) { return 0 diff --git a/consensus/parlia/parlia_test.go b/consensus/parlia/parlia_test.go index fc05013e92..6442f16466 100644 --- a/consensus/parlia/parlia_test.go +++ b/consensus/parlia/parlia_test.go @@ -5,7 +5,16 @@ import ( "math/rand" "testing" + "golang.org/x/crypto/sha3" + "github.com/ethereum/go-ethereum/common" + cmath "github.com/ethereum/go-ethereum/common/math" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/rlp" +) + +const ( + upperLimitOfVoteBlockNumber = 11 ) func TestImpactOfValidatorOutOfService(t *testing.T) { @@ -144,3 +153,449 @@ func randomAddress() common.Address { rand.Read(addrBytes) return common.BytesToAddress(addrBytes) } + +// ========================================================================= +// ======= Simulator P2P network to verify fast finality ============ +// ========================================================================= + +type MockBlock struct { + parent *MockBlock + + blockNumber uint64 + blockHash common.Hash + coinbase *MockValidator + td uint64 // Total difficulty from genesis block to current block + attestation uint64 // Vote attestation for parent block, zero means no attestation +} + +var GenesisBlock = &MockBlock{ + parent: nil, + blockNumber: 0, + blockHash: common.Hash{}, + coinbase: nil, + td: diffInTurn.Uint64(), + attestation: 0, +} + +func (b *MockBlock) Hash() (hash common.Hash) { + hasher := sha3.NewLegacyKeccak256() + rlp.Encode(hasher, []interface{}{ + b.parent, + b.blockNumber, + b.coinbase, + b.td, + b.attestation, + }) + hasher.Sum(hash[:0]) + return hash +} + +func (b *MockBlock) IsConflicted(a *MockBlock) bool { + if a.blockNumber > b.blockNumber { + p := a.parent + for ; p.blockNumber > b.blockNumber; p = p.parent { + } + + return p.blockHash != b.blockHash + } + + if a.blockNumber < b.blockNumber { + p := b.parent + for ; p.blockNumber > a.blockNumber; p = p.parent { + } + + return p.blockHash != a.blockHash + } + + return a.blockHash != b.blockHash +} + +// GetJustifiedNumberAndHash returns number and hash of the highest justified block, +// keep same func signature with consensus even if `error` will be nil definitely +func (b *MockBlock) GetJustifiedNumberAndHash() (uint64, common.Hash, error) { + justifiedBlock := GenesisBlock + for curBlock := b; curBlock.blockNumber > 1; curBlock = curBlock.parent { + // justified + if curBlock.attestation != 0 { + justifiedBlock = curBlock.parent + break + } + + } + + return justifiedBlock.blockNumber, justifiedBlock.blockHash, nil +} + +func (b *MockBlock) GetJustifiedNumber() uint64 { + justifiedBlockNumber, _, _ := b.GetJustifiedNumberAndHash() + return justifiedBlockNumber +} + +// GetFinalizedBlock returns highest finalized block, +// include current block's attestation. +func (b *MockBlock) GetFinalizedBlock() *MockBlock { + if b.blockNumber < 3 { + return GenesisBlock + } + + if b.attestation != 0 && b.parent.attestation != 0 { + return b.parent.parent + } + + return b.parent.GetFinalizedBlock() +} + +type MockValidator struct { + index int + validatorSet int // validators number + head *MockBlock + voteRecords map[uint64]*types.VoteData +} + +func NewMockValidator(index int, validatorSet int) *MockValidator { + v := &MockValidator{ + index: index, + validatorSet: validatorSet, + head: GenesisBlock, + voteRecords: make(map[uint64]*types.VoteData), + } + return v +} + +func (v *MockValidator) SignRecently() bool { + parent := v.head + for i := 0; i < v.validatorSet*1/2; i++ { + if parent.blockNumber == 0 { + return false + } + + if parent.coinbase == v { + return true + } + + parent = parent.parent + } + + return false +} + +func (v *MockValidator) Produce(attestation uint64) (*MockBlock, error) { + if v.SignRecently() { + return nil, fmt.Errorf("v %d sign recently", v.index) + } + + block := &MockBlock{ + parent: v.head, + blockNumber: v.head.blockNumber + 1, + coinbase: v, + td: v.head.td + 1, + attestation: attestation, + } + + if (block.blockNumber-1)%uint64(v.validatorSet) == uint64(v.index) { + block.td = v.head.td + 2 + } + + block.blockHash = block.Hash() + return block, nil +} + +func (v *MockValidator) Vote(block *MockBlock) bool { + // Rule 3: The block should be the latest block of canonical chain + if block != v.head { + return false + } + + // Rule 1: No double vote + if _, ok := v.voteRecords[block.blockNumber]; ok { + return false + } + + // Rule 2: No surround vote + justifiedBlockNumber, justifiedBlockHash, _ := block.GetJustifiedNumberAndHash() + for targetNumber := justifiedBlockNumber + 1; targetNumber < block.blockNumber; targetNumber++ { + if vote, ok := v.voteRecords[targetNumber]; ok { + if vote.SourceNumber > justifiedBlockNumber { + return false + } + } + } + for targetNumber := block.blockNumber; targetNumber <= block.blockNumber+upperLimitOfVoteBlockNumber; targetNumber++ { + if vote, ok := v.voteRecords[targetNumber]; ok { + if vote.SourceNumber < justifiedBlockNumber { + return false + } + } + } + + v.voteRecords[block.blockNumber] = &types.VoteData{ + SourceNumber: justifiedBlockNumber, + SourceHash: justifiedBlockHash, + TargetNumber: block.blockNumber, + TargetHash: block.blockHash, + } + return true +} + +func (v *MockValidator) InsertBlock(block *MockBlock) { + // Reject block too old. + if block.blockNumber+13 < v.head.blockNumber { + return + } + + // The higher justified block is the longest chain. + if block.GetJustifiedNumber() < v.head.GetJustifiedNumber() { + return + } + if block.GetJustifiedNumber() > v.head.GetJustifiedNumber() { + v.head = block + return + } + + // The same finalized number, the larger difficulty is the longest chain. + if block.td > v.head.td { + v.head = block + } +} + +type BlockSimulator struct { + blockNumber uint64 + coinbaseIndex int + voteMap uint64 + insertMap uint64 +} + +type ChainSimulator []*BlockSimulator + +func (s ChainSimulator) Valid() bool { + var pre *BlockSimulator + for index, bs := range s { + if index == 0 { + if bs.blockNumber != 1 { + return false + } + } else { + if bs.blockNumber != pre.blockNumber+1 { + return false + } + } + + pre = bs + } + return true +} + +type Coordinator struct { + validators []*MockValidator + attestations map[common.Hash]uint64 +} + +func NewCoordinator(validatorsNumber int) *Coordinator { + validators := make([]*MockValidator, validatorsNumber) + for i := 0; i < validatorsNumber; i++ { + validators[i] = NewMockValidator(i, validatorsNumber) + } + + return &Coordinator{ + validators: validators, + attestations: make(map[common.Hash]uint64), + } +} + +// SimulateP2P simulate a P2P network +func (c *Coordinator) SimulateP2P(cs ChainSimulator) error { + for _, bs := range cs { + parent := c.validators[bs.coinbaseIndex].head + if bs.blockNumber != parent.blockNumber+1 { + return fmt.Errorf("can't produce discontinuous block, head block: %d, expect produce: %d", parent.blockNumber, bs.blockNumber) + } + attestation := c.attestations[parent.blockHash] + block, err := c.validators[bs.coinbaseIndex].Produce(attestation) + if err != nil { + return fmt.Errorf("produce block %v error %v", bs, err) + } + + c.PropagateBlock(bs, block) + err = c.AggregateVotes(bs, block) + if err != nil { + return err + } + } + + return nil +} + +func (c *Coordinator) AggregateVotes(bs *BlockSimulator, block *MockBlock) error { + var attestation uint64 + count := 0 + for index, voteMap := 0, bs.voteMap; voteMap > 0; index, voteMap = index+1, voteMap>>1 { + if voteMap&0x1 == 0 { + continue + } + + if !c.validators[index].Vote(block) { + return fmt.Errorf("validator(%d) couldn't vote for block %d produced by validator(%d)", index, block.blockNumber, block.coinbase.index) + } + attestation |= 1 << index + count++ + } + + if count >= cmath.CeilDiv(len(c.validators)*2, 3) { + c.attestations[block.blockHash] = attestation + } + + return nil +} + +func (c *Coordinator) PropagateBlock(bs *BlockSimulator, block *MockBlock) { + for index, insertMap := 0, bs.insertMap; insertMap > 0; index, insertMap = index+1, insertMap>>1 { + if insertMap&0x1 == 0 { + continue + } + + c.validators[index].InsertBlock(block) + } +} + +func (c *Coordinator) CheckChain() bool { + // All validators highest finalized block should not be conflicted + finalizedBlocks := make([]*MockBlock, len(c.validators)) + for index, val := range c.validators { + finalizedBlocks[index] = val.head.GetFinalizedBlock() + } + + for i := 0; i < len(finalizedBlocks)-1; i++ { + for j := i + 1; j < len(finalizedBlocks); j++ { + if finalizedBlocks[i].IsConflicted(finalizedBlocks[j]) { + return false + } + } + } + + return true +} + +type TestSimulatorParam struct { + validatorsNumber int + cs ChainSimulator +} + +var simulatorTestcases = []*TestSimulatorParam{ + { + // 3 validators, all active + validatorsNumber: 3, + cs: []*BlockSimulator{ + {1, 0, 0x7, 0x7}, + {2, 1, 0x7, 0x7}, + {3, 2, 0x7, 0x7}, + {4, 0, 0x7, 0x7}, + {5, 1, 0x7, 0x7}, + }, + }, + { + // 5 validators, 4 active, 1 down + validatorsNumber: 5, + cs: []*BlockSimulator{ + {1, 0, 0x1f, 0x1f}, + {2, 1, 0x1f, 0x1f}, + {3, 2, 0x1f, 0x1f}, + {4, 3, 0x1f, 0x1f}, + {5, 0, 0x1f, 0x1f}, + {6, 1, 0x1f, 0x1f}, + {7, 2, 0x1f, 0x1f}, + }, + }, + { + // 21 validators, all active + validatorsNumber: 21, + cs: []*BlockSimulator{ + {1, 0, 0x1fffff, 0x1fffff}, + {2, 1, 0x1fffff, 0x1fffff}, + {3, 2, 0x1fffff, 0x1fffff}, + {4, 3, 0x1fffff, 0x1fffff}, + {5, 4, 0x1fffff, 0x1fffff}, + {6, 5, 0x1fffff, 0x1fffff}, + {7, 6, 0x1fffff, 0x1fffff}, + {8, 7, 0x1fffff, 0x1fffff}, + {9, 8, 0x1fffff, 0x1fffff}, + {10, 9, 0x1fffff, 0x1fffff}, + {11, 10, 0x1fffff, 0x1fffff}, + {12, 11, 0x1fffff, 0x1fffff}, + {13, 12, 0x1fffff, 0x1fffff}, + {14, 13, 0x1fffff, 0x1fffff}, + {15, 14, 0x1fffff, 0x1fffff}, + {16, 0, 0x1fffff, 0x1fffff}, + {17, 1, 0x1fffff, 0x1fffff}, + {18, 2, 0x1fffff, 0x1fffff}, + }, + }, + { + // 21 validators, all active, the finalized fork can keep grow + validatorsNumber: 21, + cs: []*BlockSimulator{ + {1, 1, 0x00fffe, 0x00fffe}, + {2, 2, 0x00fffe, 0x00fffe}, + {1, 0, 0x1f0001, 0x1fffff}, + {2, 16, 0x1f0001, 0x1ffff1}, + {3, 17, 0x1f0001, 0x1ffff1}, + {4, 18, 0x1f0001, 0x1ffff1}, + {5, 19, 0x1f0001, 0x1ffff1}, + {3, 3, 0x00fffe, 0x00fffe}, // justify block 2 and finalize block 1 + {6, 20, 0x1f0001, 0x1fffff}, + {4, 4, 0x00fffe, 0x1fffff}, + {5, 5, 0x00fffe, 0x1fffff}, + {6, 6, 0x00fffe, 0x1fffff}, + {7, 7, 0x1fffff, 0x1fffff}, + {8, 8, 0x1fffff, 0x1fffff}, + }, + }, + { + // 21 validators, all active, the finalized fork can keep grow + validatorsNumber: 21, + cs: []*BlockSimulator{ + {1, 14, 0x00fffe, 0x00fffe}, + {2, 15, 0x00fffe, 0x00fffe}, // The block 3 will never produce + {1, 0, 0x1f0001, 0x1fffff}, + {2, 16, 0x1f0001, 0x1fffff}, + {3, 1, 0x1f0001, 0x1fffff}, // based block produced by 15 + {4, 2, 0x1f0001, 0x1fffff}, + {5, 3, 0x1f0001, 0x1fffff}, + {6, 4, 0x1f0001, 0x1fffff}, + {7, 5, 0x1f0001, 0x1fffff}, + {8, 6, 0x1f0001, 0x1fffff}, + {9, 7, 0x1f0001, 0x1fffff}, + {10, 8, 0x1f0001, 0x1fffff}, + {11, 9, 0x1f0001, 0x1fffff}, + {12, 10, 0x1f0001, 0x1fffff}, + {13, 11, 0x1f0001, 0x1fffff}, + {14, 12, 0x1f0001, 0x1fffff}, + {15, 13, 0x1f0001, 0x1fffff}, + {16, 14, 0x1f0001, 0x1fffff}, + {17, 15, 0x1fffff, 0x1fffff}, // begin new round vote + {18, 16, 0x1fffff, 0x1fffff}, // attestation for block 17 + {19, 17, 0x1fffff, 0x1fffff}, // attestation for block 18 + }, + }, +} + +func TestSimulateP2P(t *testing.T) { + for index, testcase := range simulatorTestcases { + c := NewCoordinator(testcase.validatorsNumber) + err := c.SimulateP2P(testcase.cs) + if err != nil { + t.Fatalf("[Testcase %d] simulate P2P error: %v", index, err) + } + for _, val := range c.validators { + t.Logf("[Testcase %d] validator(%d) head block: %d", + index, val.index, val.head.blockNumber) + t.Logf("[Testcase %d] validator(%d) highest justified block: %d", + index, val.index, val.head.GetJustifiedNumber()) + t.Logf("[Testcase %d] validator(%d) highest finalized block: %d", + index, val.index, val.head.GetFinalizedBlock().blockNumber) + } + + if c.CheckChain() == false { + t.Fatalf("[Testcase %d] chain not works as expected", index) + } + } +} diff --git a/consensus/parlia/snapshot.go b/consensus/parlia/snapshot.go index 95aaf861de..e7a9dea460 100644 --- a/consensus/parlia/snapshot.go +++ b/consensus/parlia/snapshot.go @@ -21,16 +21,18 @@ import ( "encoding/hex" "encoding/json" "errors" - "math/big" + "fmt" "sort" + lru "github.com/hashicorp/golang-lru" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/internal/ethapi" + "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" - lru "github.com/hashicorp/golang-lru" ) // Snapshot is the state of the validatorSet at a given point. @@ -39,11 +41,17 @@ type Snapshot struct { ethAPI *ethapi.PublicBlockChainAPI sigCache *lru.ARCCache // Cache of recent block signatures to speed up ecrecover - Number uint64 `json:"number"` // Block number where the snapshot was created - Hash common.Hash `json:"hash"` // Block hash where the snapshot was created - Validators map[common.Address]struct{} `json:"validators"` // Set of authorized validators at this moment - Recents map[uint64]common.Address `json:"recents"` // Set of recent validators for spam protections - RecentForkHashes map[uint64]string `json:"recent_fork_hashes"` // Set of recent forkHash + Number uint64 `json:"number"` // Block number where the snapshot was created + Hash common.Hash `json:"hash"` // Block hash where the snapshot was created + Validators map[common.Address]*ValidatorInfo `json:"validators"` // Set of authorized validators at this moment + Recents map[uint64]common.Address `json:"recents"` // Set of recent validators for spam protections + 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 @@ -55,6 +63,7 @@ func newSnapshot( number uint64, hash common.Hash, validators []common.Address, + voteAddrs []types.BLSPublicKey, ethAPI *ethapi.PublicBlockChainAPI, ) *Snapshot { snap := &Snapshot{ @@ -65,10 +74,25 @@ func newSnapshot( Hash: hash, Recents: make(map[uint64]common.Address), RecentForkHashes: make(map[uint64]string), - Validators: make(map[common.Address]struct{}), + Validators: make(map[common.Address]*ValidatorInfo), } - for _, v := range validators { - snap.Validators[v] = struct{}{} + 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{} + } + } + + // 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 } @@ -114,13 +138,16 @@ func (s *Snapshot) copy() *Snapshot { sigCache: s.sigCache, Number: s.Number, Hash: s.Hash, - Validators: make(map[common.Address]struct{}), + Validators: make(map[common.Address]*ValidatorInfo), Recents: make(map[uint64]common.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 @@ -128,6 +155,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 } @@ -141,7 +176,38 @@ 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) (*Snapshot, error) { +func (s *Snapshot) updateAttestation(header *types.Header, chainConfig *params.ChainConfig, parliaConfig *params.ParliaConfig) { + if !chainConfig.IsLuban(header.Number) { + return + } + + // The attestation should have been checked in verify header, update directly + attestation, _ := getVoteAttestationFromHeader(header, chainConfig, parliaConfig) + if attestation == nil { + return + } + + // Headers with bad attestation are accepted before Plato upgrade, + // but Attestation of snapshot is only updated when the target block is direct parent of the header + targetNumber := attestation.Data.TargetNumber + targetHash := attestation.Data.TargetHash + if targetHash != header.ParentHash || targetNumber+1 != header.Number.Uint64() { + log.Warn("updateAttestation failed", "error", fmt.Errorf("invalid attestation, target mismatch, expected block: %d, hash: %s; real block: %d, hash: %s", + header.Number.Uint64()-1, header.ParentHash, targetNumber, targetHash)) + updateAttestationFailedGauge.Inc(1) + 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 *params.ChainConfig) (*Snapshot, error) { // Allow passing in no headers for cleaner code if len(headers) == 0 { return s, nil @@ -174,7 +240,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 } @@ -194,15 +260,20 @@ 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[common.Address]struct{}, len(newValArr)) - for _, val := range newValArr { - newVals[val] = struct{}{} + newVals := make(map[common.Address]*ValidatorInfo, len(newValArr)) + for idx, val := range newValArr { + if !chainConfig.IsLuban(header.Number) { + newVals[val] = &ValidatorInfo{} + } else { + newVals[val] = &ValidatorInfo{ + VoteAddress: voteAddrs[idx], + } + } } oldLimit := len(snap.Validators)/2 + 1 newLimit := len(newVals)/2 + 1 @@ -219,7 +290,16 @@ func (s *Snapshot) apply(headers []*types.Header, chain consensus.ChainHeaderRea } } snap.Validators = newVals + if chainConfig.IsLuban(header.Number) { + validators := snap.validators() + for idx, val := range validators { + snap.Validators[val].Index = idx + 1 // offset by 1 + } + } } + + snap.updateAttestation(header, chainConfig, s.config) + snap.RecentForkHashes[number] = hex.EncodeToString(header.Extra[extraVanity-nextForkHashSize : extraVanity]) } snap.Number += uint64(len(headers)) @@ -265,6 +345,10 @@ func (s *Snapshot) enoughDistance(validator common.Address, header *types.Header } func (s *Snapshot) indexOfVal(validator common.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 { @@ -280,18 +364,29 @@ func (s *Snapshot) supposeValidator() common.Address { return validators[index] } -func ParseValidators(validatorsBytes []byte) ([]common.Address, error) { - if len(validatorsBytes)%validatorBytesLength != 0 { - return nil, errors.New("invalid validators bytes") +func parseValidators(header *types.Header, chainConfig *params.ChainConfig, parliaConfig *params.ParliaConfig) ([]common.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) { + n := len(validatorsBytes) / validatorBytesLengthBeforeLuban + result := make([]common.Address, n) + for i := 0; i < n; i++ { + result[i] = common.BytesToAddress(validatorsBytes[i*validatorBytesLengthBeforeLuban : (i+1)*validatorBytesLengthBeforeLuban]) + } + return result, nil, nil + } + n := len(validatorsBytes) / validatorBytesLength - result := make([]common.Address, n) + cnsAddrs := make([]common.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] = common.BytesToAddress(address) + cnsAddrs[i] = common.BytesToAddress(validatorsBytes[i*validatorBytesLength : i*validatorBytesLength+common.AddressLength]) + copy(voteAddrs[i][:], validatorsBytes[i*validatorBytesLength+common.AddressLength:(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/core/blockchain.go b/core/blockchain.go index b119270b99..c67ceb2097 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -55,6 +55,9 @@ var ( headHeaderGauge = metrics.NewRegisteredGauge("chain/head/header", nil) headFastBlockGauge = metrics.NewRegisteredGauge("chain/head/receipt", nil) + justifiedBlockGauge = metrics.NewRegisteredGauge("chain/head/justified", nil) + finalizedBlockGauge = metrics.NewRegisteredGauge("chain/head/finalized", nil) + accountReadTimer = metrics.NewRegisteredTimer("chain/account/reads", nil) accountHashTimer = metrics.NewRegisteredTimer("chain/account/hashes", nil) accountUpdateTimer = metrics.NewRegisteredTimer("chain/account/updates", nil) @@ -200,16 +203,17 @@ type BlockChain struct { txLookupLimit uint64 triesInMemory uint64 - hc *HeaderChain - rmLogsFeed event.Feed - chainFeed event.Feed - chainSideFeed event.Feed - chainHeadFeed event.Feed - chainBlockFeed event.Feed - logsFeed event.Feed - blockProcFeed event.Feed - scope event.SubscriptionScope - genesisBlock *types.Block + hc *HeaderChain + rmLogsFeed event.Feed + chainFeed event.Feed + chainSideFeed event.Feed + chainHeadFeed event.Feed + chainBlockFeed event.Feed + logsFeed event.Feed + blockProcFeed event.Feed + finalizedHeaderFeed event.Feed + scope event.SubscriptionScope + genesisBlock *types.Block // This mutex synchronizes chain write operations. // Readers don't need to take it, they can just read the database. @@ -590,6 +594,30 @@ func (bc *BlockChain) empty() bool { return true } +// GetJustifiedNumber returns the highest justified blockNumber on the branch including and before `header`. +func (bc *BlockChain) GetJustifiedNumber(header *types.Header) uint64 { + if p, ok := bc.engine.(consensus.PoSA); ok { + justifiedBlockNumber, _, err := p.GetJustifiedNumberAndHash(bc, header) + if err == nil { + return justifiedBlockNumber + } + } + // return 0 when err!=nil + // so the input `header` will at a disadvantage during reorg + return 0 +} + +// getFinalizedNumber returns the highest finalized number before the specific block. +func (bc *BlockChain) getFinalizedNumber(header *types.Header) uint64 { + if p, ok := bc.engine.(consensus.PoSA); ok { + if finalizedHeader := p.GetFinalizedHeader(bc, header); finalizedHeader != nil { + return finalizedHeader.Number.Uint64() + } + } + + return 0 +} + // loadLastState loads the last known chain state from the database. This method // assumes that the chain manager mutex is held. func (bc *BlockChain) loadLastState() error { @@ -611,6 +639,8 @@ func (bc *BlockChain) loadLastState() error { // Everything seems to be fine, set as the head block bc.currentBlock.Store(currentBlock) headBlockGauge.Update(int64(currentBlock.NumberU64())) + justifiedBlockGauge.Update(int64(bc.GetJustifiedNumber(currentBlock.Header()))) + finalizedBlockGauge.Update(int64(bc.getFinalizedNumber(currentBlock.Header()))) // Restore the last known head header currentHeader := currentBlock.Header() @@ -759,6 +789,8 @@ func (bc *BlockChain) setHeadBeyondRoot(head uint64, root common.Hash, repair bo // to low, so it's safe to update in-memory markers directly. bc.currentBlock.Store(newHeadBlock) headBlockGauge.Update(int64(newHeadBlock.NumberU64())) + justifiedBlockGauge.Update(int64(bc.GetJustifiedNumber(newHeadBlock.Header()))) + finalizedBlockGauge.Update(int64(bc.getFinalizedNumber(newHeadBlock.Header()))) } // Rewind the fast block in a simpleton way to the target head if currentFastBlock := bc.CurrentFastBlock(); currentFastBlock != nil && header.Number.Uint64() < currentFastBlock.NumberU64() { @@ -849,6 +881,8 @@ func (bc *BlockChain) SnapSyncCommitHead(hash common.Hash) error { } bc.currentBlock.Store(block) headBlockGauge.Update(int64(block.NumberU64())) + justifiedBlockGauge.Update(int64(bc.GetJustifiedNumber(block.Header()))) + finalizedBlockGauge.Update(int64(bc.getFinalizedNumber(block.Header()))) bc.chainmu.Unlock() // Destroy any existing state snapshot and regenerate it in the background, @@ -895,6 +929,8 @@ func (bc *BlockChain) ResetWithGenesisBlock(genesis *types.Block) error { bc.genesisBlock = genesis bc.currentBlock.Store(bc.genesisBlock) headBlockGauge.Update(int64(bc.genesisBlock.NumberU64())) + justifiedBlockGauge.Update(int64(bc.genesisBlock.NumberU64())) + finalizedBlockGauge.Update(int64(bc.genesisBlock.NumberU64())) bc.hc.SetGenesis(bc.genesisBlock.Header()) bc.hc.SetCurrentHeader(bc.genesisBlock.Header()) bc.currentFastBlock.Store(bc.genesisBlock) @@ -966,6 +1002,8 @@ func (bc *BlockChain) writeHeadBlock(block *types.Block) { bc.currentBlock.Store(block) headBlockGauge.Update(int64(block.NumberU64())) + justifiedBlockGauge.Update(int64(bc.GetJustifiedNumber(block.Header()))) + finalizedBlockGauge.Update(int64(bc.getFinalizedNumber(block.Header()))) } // GetDiffLayerRLP retrieves a diff layer in RLP encoding from the cache or database by blockHash @@ -1203,7 +1241,7 @@ func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain [ // Rewind may have occurred, skip in that case. if bc.CurrentHeader().Number.Cmp(head.Number()) >= 0 { - reorg, err := bc.forker.ReorgNeeded(bc.CurrentFastBlock().Header(), head.Header()) + reorg, err := bc.forker.ReorgNeededWithFastFinality(bc.CurrentFastBlock().Header(), head.Header()) if err != nil { log.Warn("Reorg failed", "err", err) return false @@ -1546,14 +1584,20 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types. } } // Garbage collect anything below our required write retention + wg2 := sync.WaitGroup{} for !bc.triegc.Empty() { root, number := bc.triegc.Pop() if uint64(-number) > chosen { bc.triegc.Push(root, number) break } - go triedb.Dereference(root.(common.Hash)) + wg2.Add(1) + go func() { + triedb.Dereference(root.(common.Hash)) + wg2.Done() + }() } + wg2.Wait() } } return nil @@ -1601,7 +1645,7 @@ func (bc *BlockChain) writeBlockAndSetHead(block *types.Block, receipts []*types return NonStatTy, err } currentBlock := bc.CurrentBlock() - reorg, err := bc.forker.ReorgNeeded(currentBlock.Header(), block.Header()) + reorg, err := bc.forker.ReorgNeededWithFastFinality(currentBlock.Header(), block.Header()) if err != nil { return NonStatTy, err } @@ -1634,6 +1678,11 @@ func (bc *BlockChain) writeBlockAndSetHead(block *types.Block, receipts []*types // event here. if emitHeadEvent { bc.chainHeadFeed.Send(ChainHeadEvent{Block: block}) + if posa, ok := bc.Engine().(consensus.PoSA); ok { + if finalizedHeader := posa.GetFinalizedHeader(bc, block.Header()); finalizedHeader != nil { + bc.finalizedHeaderFeed.Send(FinalizedHeaderEvent{finalizedHeader}) + } + } } } else { bc.chainSideFeed.Send(ChainSideEvent{Block: block}) @@ -1721,6 +1770,11 @@ func (bc *BlockChain) insertChain(chain types.Blocks, verifySeals, setHead bool) defer func() { if lastCanon != nil && bc.CurrentBlock().Hash() == lastCanon.Hash() { bc.chainHeadFeed.Send(ChainHeadEvent{lastCanon}) + if posa, ok := bc.Engine().(consensus.PoSA); ok { + if finalizedHeader := posa.GetFinalizedHeader(bc, lastCanon.Header()); finalizedHeader != nil { + bc.finalizedHeaderFeed.Send(FinalizedHeaderEvent{finalizedHeader}) + } + } } }() // Start the parallel header verifier @@ -1750,7 +1804,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks, verifySeals, setHead bool) current = bc.CurrentBlock() ) for block != nil && bc.skipBlock(err, it) { - reorg, err = bc.forker.ReorgNeeded(current.Header(), block.Header()) + reorg, err = bc.forker.ReorgNeededWithFastFinality(current.Header(), block.Header()) if err != nil { return it.index, err } @@ -2128,7 +2182,7 @@ func (bc *BlockChain) insertSideChain(block *types.Block, it *insertIterator) (i // // If the externTd was larger than our local TD, we now need to reimport the previous // blocks to regenerate the required state - reorg, err := bc.forker.ReorgNeeded(current.Header(), lastBlock.Header()) + reorg, err := bc.forker.ReorgNeededWithFastFinality(current.Header(), lastBlock.Header()) if err != nil { return it.index, err } diff --git a/core/blockchain_reader.go b/core/blockchain_reader.go index b28661da3e..d4b11aa3f0 100644 --- a/core/blockchain_reader.go +++ b/core/blockchain_reader.go @@ -42,6 +42,36 @@ func (bc *BlockChain) CurrentBlock() *types.Block { return bc.currentBlock.Load().(*types.Block) } +// CurrentFinalBlock retrieves the current finalized block of the canonical +// chain. The block is retrieved from the blockchain's internal cache. +func (bc *BlockChain) CurrentFinalBlock() *types.Header { + if p, ok := bc.engine.(consensus.PoSA); ok { + currentHeader := bc.CurrentHeader() + if currentHeader == nil { + return nil + } + return p.GetFinalizedHeader(bc, currentHeader) + } + + return nil +} + +// CurrentSafeBlock retrieves the current safe block of the canonical +// chain. The block is retrieved from the blockchain's internal cache. +func (bc *BlockChain) CurrentSafeBlock() *types.Header { + if p, ok := bc.engine.(consensus.PoSA); ok { + currentHeader := bc.CurrentHeader() + if currentHeader == nil { + return nil + } + _, justifiedBlockHash, err := p.GetJustifiedNumberAndHash(bc, currentHeader) + if err == nil { + return bc.GetHeaderByHash(justifiedBlockHash) + } + } + return nil +} + // CurrentFastBlock retrieves the current fast-sync head block of the canonical // chain. The block is retrieved from the blockchain's internal cache. func (bc *BlockChain) CurrentFastBlock() *types.Block { @@ -399,3 +429,8 @@ func (bc *BlockChain) SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscript func (bc *BlockChain) SubscribeBlockProcessingEvent(ch chan<- bool) event.Subscription { return bc.scope.Track(bc.blockProcFeed.Subscribe(ch)) } + +// SubscribeFinalizedHeaderEvent registers a subscription of FinalizedHeaderEvent. +func (bc *BlockChain) SubscribeFinalizedHeaderEvent(ch chan<- FinalizedHeaderEvent) event.Subscription { + return bc.scope.Track(bc.finalizedHeaderFeed.Subscribe(ch)) +} diff --git a/core/events.go b/core/events.go index 5e730a24a7..ce8bcca744 100644 --- a/core/events.go +++ b/core/events.go @@ -21,7 +21,7 @@ import ( "github.com/ethereum/go-ethereum/core/types" ) -// NewTxsEvent is posted when a batch of transactions enter the transaction pool. +// NewTxsEvent is posted when a batch of transactions enters the transaction pool. type NewTxsEvent struct{ Txs []*types.Transaction } // ReannoTxsEvent is posted when a batch of local pending transactions exceed a specified duration. @@ -33,6 +33,12 @@ type NewMinedBlockEvent struct{ Block *types.Block } // RemovedLogsEvent is posted when a reorg happens type RemovedLogsEvent struct{ Logs []*types.Log } +// NewVoteEvent is posted when a batch of votes enters the vote pool. +type NewVoteEvent struct{ Vote *types.VoteEnvelope } + +// FinalizedHeaderEvent is posted when a finalized header is reached. +type FinalizedHeaderEvent struct{ Header *types.Header } + type ChainEvent struct { Block *types.Block Hash common.Hash diff --git a/core/forkchoice.go b/core/forkchoice.go index b0dbb200ec..452c084ee7 100644 --- a/core/forkchoice.go +++ b/core/forkchoice.go @@ -24,6 +24,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/math" + "github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" @@ -36,6 +37,12 @@ type ChainReader interface { // Config retrieves the header chain's chain configuration. Config() *params.ChainConfig + // Engine retrieves the blockchain's consensus engine. + Engine() consensus.Engine + + // GetJustifiedNumber returns the highest justified blockNumber on the branch including and before `header` + GetJustifiedNumber(header *types.Header) uint64 + // GetTd returns the total difficulty of a local block. GetTd(common.Hash, uint64) *big.Int } @@ -69,12 +76,12 @@ func NewForkChoice(chainReader ChainReader, preserve func(header *types.Header) } } -// ReorgNeeded returns whether the reorg should be applied +// reorgNeeded returns whether the reorg should be applied // based on the given external header and local canonical chain. // In the td mode, the new head is chosen if the corresponding // total difficulty is higher. In the extern mode, the trusted // header is always selected as the head. -func (f *ForkChoice) ReorgNeeded(current *types.Header, header *types.Header) (bool, error) { +func (f *ForkChoice) reorgNeeded(current *types.Header, header *types.Header) (bool, error) { var ( localTD = f.chain.GetTd(current.Hash(), current.Number.Uint64()) externTd = f.chain.GetTd(header.Hash(), header.Number.Uint64()) @@ -106,3 +113,24 @@ func (f *ForkChoice) ReorgNeeded(current *types.Header, header *types.Header) (b } return reorg, nil } + +// ReorgNeededWithFastFinality compares justified block numbers firstly, backoff to compare tds when equal +func (f *ForkChoice) ReorgNeededWithFastFinality(current *types.Header, header *types.Header) (bool, error) { + _, ok := f.chain.Engine().(consensus.PoSA) + if !ok { + return f.reorgNeeded(current, header) + } + + justifiedNumber, curJustifiedNumber := uint64(0), uint64(0) + if f.chain.Config().IsPlato(header.Number) { + justifiedNumber = f.chain.GetJustifiedNumber(header) + } + if f.chain.Config().IsPlato(current.Number) { + curJustifiedNumber = f.chain.GetJustifiedNumber(current) + } + if justifiedNumber == curJustifiedNumber { + return f.reorgNeeded(current, header) + } + + return justifiedNumber > curJustifiedNumber, nil +} diff --git a/core/headerchain.go b/core/headerchain.go index c55f7c32c7..88ad7593bd 100644 --- a/core/headerchain.go +++ b/core/headerchain.go @@ -109,9 +109,36 @@ func NewHeaderChain(chainDb ethdb.Database, config *params.ChainConfig, engine c } hc.currentHeaderHash = hc.CurrentHeader().Hash() headHeaderGauge.Update(hc.CurrentHeader().Number.Int64()) + justifiedBlockGauge.Update(int64(hc.GetJustifiedNumber(hc.CurrentHeader()))) + finalizedBlockGauge.Update(int64(hc.getFinalizedNumber(hc.CurrentHeader()))) + return hc, nil } +// GetJustifiedNumber returns the highest justified blockNumber on the branch including and before `header`. +func (hc *HeaderChain) GetJustifiedNumber(header *types.Header) uint64 { + if p, ok := hc.engine.(consensus.PoSA); ok { + justifiedBlockNumber, _, err := p.GetJustifiedNumberAndHash(hc, header) + if err == nil { + return justifiedBlockNumber + } + } + // return 0 when err!=nil + // so the input `header` will at a disadvantage during reorg + return 0 +} + +// getFinalizedNumber returns the highest finalized number before the specific block. +func (hc *HeaderChain) getFinalizedNumber(header *types.Header) uint64 { + if p, ok := hc.engine.(consensus.PoSA); ok { + if finalizedHeader := p.GetFinalizedHeader(hc, header); finalizedHeader != nil { + return finalizedHeader.Number.Uint64() + } + } + + return 0 +} + // GetBlockNumber retrieves the block number belonging to the given hash // from the cache or database func (hc *HeaderChain) GetBlockNumber(hash common.Hash) *uint64 { @@ -285,7 +312,7 @@ func (hc *HeaderChain) writeHeadersAndSetHead(headers []*types.Header, forker *F } ) // Ask the fork choicer if the reorg is necessary - if reorg, err := forker.ReorgNeeded(hc.CurrentHeader(), lastHeader); err != nil { + if reorg, err := forker.ReorgNeededWithFastFinality(hc.CurrentHeader(), lastHeader); err != nil { return nil, err } else if !reorg { if inserted != 0 { @@ -583,6 +610,8 @@ func (hc *HeaderChain) SetCurrentHeader(head *types.Header) { hc.currentHeader.Store(head) hc.currentHeaderHash = head.Hash() headHeaderGauge.Update(head.Number.Int64()) + justifiedBlockGauge.Update(int64(hc.GetJustifiedNumber(head))) + finalizedBlockGauge.Update(int64(hc.getFinalizedNumber(head))) } type ( @@ -638,6 +667,8 @@ func (hc *HeaderChain) SetHead(head uint64, updateFn UpdateHeadBlocksCallback, d hc.currentHeader.Store(parent) hc.currentHeaderHash = parentHash headHeaderGauge.Update(parent.Number.Int64()) + justifiedBlockGauge.Update(int64(hc.GetJustifiedNumber(parent))) + finalizedBlockGauge.Update(int64(hc.getFinalizedNumber(parent))) // If this is the first iteration, wipe any leftover data upwards too so // we don't end up with dangling daps in the database diff --git a/core/state/snapshot/generate.go b/core/state/snapshot/generate.go index 9d74ca4d9b..98fa40ad2e 100644 --- a/core/state/snapshot/generate.go +++ b/core/state/snapshot/generate.go @@ -199,7 +199,7 @@ func journalProgress(db ethdb.KeyValueWriter, marker []byte, stats *generatorSta default: logstr = fmt.Sprintf("%#x:%#x", marker[:common.HashLength], marker[common.HashLength:]) } - log.Debug("Journalled generator progress", "progress", logstr) + log.Debug("Journaled generator progress", "progress", logstr) rawdb.WriteSnapshotGenerator(db, blob) } diff --git a/core/state/statedb.go b/core/state/statedb.go index 617dbfa1b7..e4a5e876f5 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -251,6 +251,7 @@ func (s *StateDB) StopPrefetcher() { s.prefetcherLock.Lock() if s.prefetcher != nil { s.prefetcher.close() + s.prefetcher = nil } s.prefetcherLock.Unlock() } @@ -456,6 +457,14 @@ func (s *StateDB) GetCode(addr common.Address) []byte { return nil } +func (s *StateDB) GetRoot(addr common.Address) common.Hash { + stateObject := s.getStateObject(addr) + if stateObject != nil { + return stateObject.data.Root + } + return common.Hash{} +} + func (s *StateDB) GetCodeSize(addr common.Address) int { stateObject := s.getStateObject(addr) if stateObject != nil { diff --git a/core/systemcontracts/upgrade.go b/core/systemcontracts/upgrade.go index 3255a4605b..e323035b24 100644 --- a/core/systemcontracts/upgrade.go +++ b/core/systemcontracts/upgrade.go @@ -51,6 +51,8 @@ var ( moranUpgrade = make(map[string]*Upgrade) planckUpgrade = make(map[string]*Upgrade) + + lubanUpgrade = make(map[string]*Upgrade) ) func init() { @@ -551,6 +553,98 @@ func init() { }, } + lubanUpgrade[mainNet] = &Upgrade{ + UpgradeName: "luban", + Configs: []*UpgradeConfig{ + { + ContractAddr: common.HexToAddress(ValidatorContract), + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/b144718e94d7a1ebb24a7103202300f08826f369", + Code: "60806040526004361061046c5760003560e01c8063862498821161024a578063c6d3394511610139578063e40716a1116100b6578063f9a2bbc71161007a578063f9a2bbc714610b6b578063fc3e590814610b80578063fccc281314610b95578063fd4ad81f14610baa578063fd6a687914610bd957610473565b8063e40716a114610af9578063eb57e20214610b0e578063eda5868c14610b2e578063f340fa0114610b43578063f92eb86b14610b5657610473565b8063d86222d5116100fd578063d86222d514610a90578063daacdb6614610aa5578063dc927faf14610aba578063e086c7b114610acf578063e1c7392a14610ae457610473565b8063c6d3394514610a3c578063c81b166214610a51578063c8509d811461085f578063d04aa99614610a66578063d68fb56a14610a7b57610473565b8063a5422d5c116101c7578063ad3c9da61161018b578063ad3c9da6146109d0578063aef198a9146109f0578063b7ab4db514610a05578063b8cf4ef114610a27578063bf9f49951461062f57610473565b8063a5422d5c1461095c578063a78abc1614610971578063aaf5eb6814610986578063ab51bb961461099b578063ac431751146109b057610473565b806396713da91161020e57806396713da9146108f35780639dc09262146109085780639fe0f8161461091d578063a0dc275814610932578063a1a11bf51461094757610473565b8063862498821461087f57806388b32f11146108945780638b5ad0c9146108a95780638d19a410146108be5780639369d7de146108de57610473565b80634df6e0c3116103665780636e47b482116102e35780637942fd05116102a75780637942fd05146108205780637a84ca2a1461083557806381650b621461084a578063831d65d11461085f578063853230aa1461080b57610473565b80636e47b482146107b757806370fd5bad146107cc578063718a8aa8146107e157806375d47a0a146107f657806378dfed4a1461080b57610473565b8063565c56b31161032a578063565c56b3146107265780635667515a146107465780635d77156c1461075b57806362b72cf5146107705780636969a25c1461078557610473565b80634df6e0c3146106b25780635192c82c146106c757806351e80672146106dc578063549b03f2146106f157806355614fcc1461070657610473565b8063321d398a116103f45780633dffc387116103b85780633dffc3871461062f57806343756e5c1461065157806345cf9daf14610666578063493279b11461067b5780634bf6c8821461069d57610473565b8063321d398a146105975780633365af3a146105b757806335409f7f146105d75780633b071dcc146105f75780633de0f0d81461061a57610473565b80631182b8751161043b5780631182b875146104fe578063152ad3b81461052b5780631ff180691461054d578063219f22d514610562578063300c35671461057757610473565b806304c4fec61461047857806307a568471461048f5780630bee7a67146104ba5780630e2374a5146104dc57610473565b3661047357005b600080fd5b34801561048457600080fd5b5061048d610bee565b005b34801561049b57600080fd5b506104a4610c60565b6040516104b19190616ef0565b60405180910390f35b3480156104c657600080fd5b506104cf610c66565b6040516104b19190616f1a565b3480156104e857600080fd5b506104f1610c6b565b6040516104b191906162f7565b34801561050a57600080fd5b5061051e6105193660046161dd565b610c71565b6040516104b1919061646e565b34801561053757600080fd5b50610540610ea9565b6040516104b19190616463565b34801561055957600080fd5b506104a4610eb2565b34801561056e57600080fd5b506104cf610eb8565b34801561058357600080fd5b5061048d6105923660046160a6565b610ebd565b3480156105a357600080fd5b506105406105b236600461618a565b611241565b3480156105c357600080fd5b506105406105d236600461618a565b611310565b3480156105e357600080fd5b5061048d6105f236600461607f565b6113c1565b34801561060357600080fd5b5061060c61151a565b6040516104b1929190616379565b34801561062657600080fd5b506104a46117f6565b34801561063b57600080fd5b506106446117fc565b6040516104b19190616f2b565b34801561065d57600080fd5b506104f1611801565b34801561067257600080fd5b506104a4611807565b34801561068757600080fd5b5061069061180d565b6040516104b19190616ee1565b3480156106a957600080fd5b50610644611812565b3480156106be57600080fd5b5061060c611817565b3480156106d357600080fd5b506104a4611995565b3480156106e857600080fd5b506104f161199b565b3480156106fd57600080fd5b506104a46119a1565b34801561071257600080fd5b5061054061072136600461607f565b6119a7565b34801561073257600080fd5b506104a461074136600461607f565b6119dc565b34801561075257600080fd5b50610644611a2d565b34801561076757600080fd5b506104cf611a32565b34801561077c57600080fd5b506104a4611a37565b34801561079157600080fd5b506107a56107a036600461618a565b611a3d565b6040516104b196959493929190616324565b3480156107c357600080fd5b506104f1611aa1565b3480156107d857600080fd5b50610644611aa7565b3480156107ed57600080fd5b50610644611aac565b34801561080257600080fd5b506104f1611ab1565b34801561081757600080fd5b506104a4611ab7565b34801561082c57600080fd5b50610644611abd565b34801561084157600080fd5b506104a4611ac2565b34801561085657600080fd5b506104cf611ac8565b34801561086b57600080fd5b5061048d61087a3660046161dd565b611acd565b34801561088b57600080fd5b506104a4611b2e565b3480156108a057600080fd5b506104a4611b34565b3480156108b557600080fd5b506104a4611b3a565b3480156108ca57600080fd5b506104a46108d936600461607f565b611b40565b3480156108ea57600080fd5b5061048d611b80565b3480156108ff57600080fd5b50610644611c94565b34801561091457600080fd5b506104f1611c99565b34801561092957600080fd5b506104a4611c9f565b34801561093e57600080fd5b506104a4611ca4565b34801561095357600080fd5b506104f1611ca9565b34801561096857600080fd5b5061051e611caf565b34801561097d57600080fd5b50610540611cce565b34801561099257600080fd5b506104a4611cd7565b3480156109a757600080fd5b506104cf611a2d565b3480156109bc57600080fd5b5061048d6109cb36600461612e565b611ce0565b3480156109dc57600080fd5b506104a46109eb36600461607f565b61258c565b3480156109fc57600080fd5b506104a461259e565b348015610a1157600080fd5b50610a1a6125ab565b6040516104b19190616366565b348015610a3357600080fd5b506104a4612697565b348015610a4857600080fd5b506104a4611aa7565b348015610a5d57600080fd5b506104f161269c565b348015610a7257600080fd5b506104a46126a2565b348015610a8757600080fd5b506104a46126a7565b348015610a9c57600080fd5b506104a46126e6565b348015610ab157600080fd5b506104a46126f2565b348015610ac657600080fd5b506104f16126f8565b348015610adb57600080fd5b506104a46126fe565b348015610af057600080fd5b5061048d612703565b348015610b0557600080fd5b506104a46128b2565b348015610b1a57600080fd5b5061048d610b2936600461607f565b6128b8565b348015610b3a57600080fd5b506104cf6129c0565b61048d610b5136600461607f565b6129c5565b348015610b6257600080fd5b506104a4612c4d565b348015610b7757600080fd5b506104f1612c53565b348015610b8c57600080fd5b50610644611c9f565b348015610ba157600080fd5b506104f1612c59565b348015610bb657600080fd5b50610bca610bc536600461618a565b612c5f565b6040516104b193929190616ef9565b348015610be557600080fd5b506104f1612d21565b6000610bf933611b40565b9050600b8181548110610c0857fe5b600091825260209091206001601690920201015460ff16610c445760405162461bcd60e51b8152600401610c3b90616b99565b60405180910390fd5b6000610c4e6126a7565b9050610c5b338383612d27565b505050565b60095481565b606481565b61200181565b60005460609060ff16610c965760405162461bcd60e51b8152600401610c3b9061662d565b3361200014610cb75760405162461bcd60e51b8152600401610c3b90616d78565b600b54610d7557610cc6615d6b565b60015460005b81811015610d7157600b80546001810182556000919091528351600080516020616fa383398151915260169092029182019081556020808601516000805160206175d28339815191528401805460ff1916911515919091179055604086015180518794610d4d93600080516020616fc3833981519152909101920190615d9a565b506060820151610d639060038301906013615e14565b505050806001019050610ccc565b5050505b610d7d615e41565b6000610dbe85858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612f1392505050565b9150915080610dda57610dd160646130cf565b92505050610ea2565b815160009060ff16610dff57610df883602001518460400151613130565b9050610e6e565b825160ff1660011415610e6a57826020015151600114610e4457600080516020616f83833981519152604051610e3490616a80565b60405180910390a1506067610e65565b610df88360200151600081518110610e5857fe5b6020026020010151613d84565b610e6e565b5060655b63ffffffff8116610e935750506040805160008152602081019091529150610ea29050565b610e9c816130cf565b93505050505b9392505050565b60075460ff1681565b60035481565b606881565b334114610edc5760405162461bcd60e51b8152600401610c3b90616dc7565b6010544311610efd5760405162461bcd60e51b8152600401610c3b90616789565b60005460ff16610f1f5760405162461bcd60e51b8152600401610c3b9061662d565b600f54610f37576032600f5561100231601155611237565b60006110023168056bc75e2d63100000811115610f6657610f5f81606463ffffffff613efb16565b9150610faf565b601154811115610fa857610f5f6064610f9c600f54610f9060115486613f3d90919063ffffffff16565b9063ffffffff613f7f16565b9063ffffffff613efb16565b5050611237565b6040516309a99b4f60e41b815261100290639a99b4f090610fd6903090869060040161630b565b602060405180830381600087803b158015610ff057600080fd5b505af1158015611004573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061102891906161a2565b6110023160115591508161103d575050611237565b6000805b8481101561106b5785858281811061105557fe5b9050602002013582019150806001019050611041565b508061107957505050611237565b6000806000805b8981101561122f578489898381811061109557fe5b905060200201358802816110a557fe5b0493508a8a828181106110b457fe5b90506020020160208101906110c9919061607f565b6001600160a01b038116600090815260046020526040902054909350915081156111e55760006001808403815481106110fe57fe5b9060005260206000209060040201905080600201601c9054906101000a900460ff161561116b57836001600160a01b03167fb9c75cbbfde137c4281689580799ef5f52144e78858f776a5979b2b212137d858660405161115e9190616ef0565b60405180910390a26111df565b60035461117e908663ffffffff613fb916565b6003908155810154611196908663ffffffff613fb916565b60038201556040516001600160a01b038516907fcb0aad6cf9cd03bdf6137e359f541c42f38b39f007cae8e89e88aa7d8c6617b2906111d6908890616ef0565b60405180910390a25b50611227565b826001600160a01b03167fb9c75cbbfde137c4281689580799ef5f52144e78858f776a5979b2b212137d858560405161121e9190616ef0565b60405180910390a25b600101611080565b505050505050505b5050436010555050565b60015460009082106112555750600061130b565b60006001600160a01b03166001838154811061126d57fe5b60009182526020909120600490910201546001600160a01b0316148061129d5750600854158061129d5750600a54155b806112ac575060085460095410155b806112bd57506112bb82611310565b155b806112e657506000600b83815481106112d257fe5b906000526020600020906016020160000154115b806112fa575060016112f66125ab565b5111155b156113075750600061130b565b5060015b919050565b60015460009082106113245750600061130b565b600b548210611361576001828154811061133a57fe5b9060005260206000209060040201600201601c9054906101000a900460ff1615905061130b565b6001828154811061136e57fe5b9060005260206000209060040201600201601c9054906101000a900460ff161580156113bb5750600b82815481106113a257fe5b600091825260209091206001601690920201015460ff16155b92915050565b33611001146113e25760405162461bcd60e51b8152600401610c3b90616e98565b600b546114a0576113f1615d6b565b60015460005b8181101561149c57600b80546001810182556000919091528351600080516020616fa383398151915260169092029182019081556020808601516000805160206175d28339815191528401805460ff191691151591909117905560408601518051879461147893600080516020616fc3833981519152909101920190615d9a565b50606082015161148e9060038301906013615e14565b5050508060010190506113f7565b5050505b6001600160a01b038116600090815260046020526040902054806114c45750611517565b6001810390506000600b82815481106114d957fe5b600091825260209091206001601690920201015460ff1690506114fc8383613fde565b80156115055750805b15610c5b576009805460001901905550505b50565b60015460609081906000805b8281101561156d576001818154811061153b57fe5b9060005260206000209060040201600201601c9054906101000a900460ff16611565576001909101905b600101611526565b5060608160405190808252806020026020018201604052801561159a578160200160208202803683370190505b5090506060826040519080825280602002602001820160405280156115d357816020015b60608152602001906001900390816115be5790505b50600b546000945090915084141561174e5760005b8481101561174857600181815481106115fd57fe5b9060005260206000209060040201600201601c9054906101000a900460ff16611740576001818154811061162d57fe5b600091825260209091206004909102015483516001600160a01b039091169084908690811061165857fe5b60200260200101906001600160a01b031690816001600160a01b031681525050600b818154811061168557fe5b600091825260209182902060026016909202018101805460408051601f60001961010060018616150201909316949094049182018590048502840185019052808352919290919083018282801561171d5780601f106116f25761010080835404028352916020019161171d565b820191906000526020600020905b81548152906001019060200180831161170057829003601f168201915b505050505082858151811061172e57fe5b60209081029190910101526001909301925b6001016115e8565b506117ea565b60005b848110156117e8576001818154811061176657fe5b9060005260206000209060040201600201601c9054906101000a900460ff166117e0576001818154811061179657fe5b600091825260209091206004909102015483516001600160a01b03909116908490869081106117c157fe5b6001600160a01b03909216602092830291909101909101526001909301925b600101611751565b505b909450925050505b9091565b61271081565b600181565b61100181565b60085481565b603881565b600881565b600e54600c5460609182918061182b575060155b60606118356125ab565b9050606061184282614391565b9050828251116118595790945092506117f2915050565b8383835103101561186b578282510393505b83156118a15760c8430461188783838388880360008a8a6144ff565b61189f8383838888038989038a8b8b8b5103016144ff565b505b6060836040519080825280602002602001820160405280156118cd578160200160208202803683370190505b50905060608460405190808252806020026020018201604052801561190657816020015b60608152602001906001900390816118f15790505b50905060005b858110156119875784818151811061192057fe5b602002602001015183828151811061193457fe5b60200260200101906001600160a01b031690816001600160a01b03168152505083818151811061196057fe5b602002602001015182828151811061197457fe5b602090810291909101015260010161190c565b509096509450505050509091565b60065481565b61200081565b600f5481565b6001600160a01b038116600090815260046020526040812054806119cf57600091505061130b565b60001901610ea281611310565b6001600160a01b03811660009081526004602052604081205480611a0457600091505061130b565b600180820381548110611a1357fe5b906000526020600020906004020160030154915050919050565b600081565b606781565b60105481565b60018181548110611a4a57fe5b600091825260209091206004909102018054600182015460028301546003909301546001600160a01b0392831694509082169291821691600160a01b81046001600160401b031691600160e01b90910460ff169086565b61100581565b600281565b601081565b61100881565b6103e881565b600b81565b600c5481565b606681565b3361200014611aee5760405162461bcd60e51b8152600401610c3b90616d78565b7f41ce201247b6ceb957dcdb217d0b8acb50b9ea0e12af9af4f5e7f38902101605838383604051611b2193929190616f39565b60405180910390a1505050565b60025481565b60115481565b600a5481565b6001600160a01b03811660009081526004602052604081205480611b765760405162461bcd60e51b8152600401610c3b90616d00565b6000190192915050565b600b54611c3e57611b8f615d6b565b60015460005b81811015611c3a57600b80546001810182556000919091528351600080516020616fa383398151915260169092029182019081556020808601516000805160206175d28339815191528401805460ff1916911515919091179055604086015180518794611c1693600080516020616fc3833981519152909101920190615d9a565b506060820151611c2c9060038301906013615e14565b505050806001019050611b95565b5050505b600854611c4b5760036008555b600a54611c58576002600a555b6000611c6333611b40565b9050611c6e81611241565b611c8a5760405162461bcd60e51b8152600401610c3b90616a3d565b6115173382614656565b600981565b61100781565b600381565b60c881565b61100681565b6040518061062001604052806105ef8152602001616fe36105ef913981565b60005460ff1681565b6402540be40081565b60005460ff16611d025760405162461bcd60e51b8152600401610c3b9061662d565b3361100714611d235760405162461bcd60e51b8152600401610c3b90616b06565b611d8d84848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526013815272065787069726554696d655365636f6e6447617606c1b602082015291506146ee9050565b15611e2a5760208114611db25760405162461bcd60e51b8152600401610c3b90616cba565b604080516020601f8401819004810282018101909252828152600091611df09185858083850183828082843760009201919091525061474792505050565b905060648110158015611e065750620186a08111155b611e225760405162461bcd60e51b8152600401610c3b906168e6565b600255612549565b611e8a84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260098152686275726e526174696f60b81b602082015291506146ee9050565b15611f265760208114611eaf5760405162461bcd60e51b8152600401610c3b906164b3565b604080516020601f8401819004810282018101909252828152600091611eed9185858083850183828082843760009201919091525061474792505050565b9050612710811115611f115760405162461bcd60e51b8152600401610c3b906167cb565b6006556007805460ff19166001179055612549565b611f9084848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260138152726d61784e756d4f664d61696e7461696e696e6760681b602082015291506146ee9050565b1561202a5760208114611fb55760405162461bcd60e51b8152600401610c3b906164ea565b604080516020601f8401819004810282018101909252828152600091611ff39185858083850183828082843760009201919091525061474792505050565b600c5490915080612002575060155b8082106120215760405162461bcd60e51b8152600401610c3b9061683e565b50600855612549565b61209384848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260128152716d61696e7461696e536c6173685363616c6560701b602082015291506146ee9050565b1561212c57602081146120b85760405162461bcd60e51b8152600401610c3b906165b3565b604080516020601f84018190048102820181019092528281526000916120f69185858083850183828082843760009201919091525061474792505050565b90506000811180156121085750600a81105b6121245760405162461bcd60e51b8152600401610c3b90616e14565b600a55612549565b6121a084848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601981527f6d61784e756d4f66576f726b696e6743616e6469646174657300000000000000602082015291506146ee9050565b1561222f57602081146121c55760405162461bcd60e51b8152600401610c3b90616567565b604080516020601f84018190048102820181019092528281526000916122039185858083850183828082843760009201919091525061474792505050565b9050600d548111156122275760405162461bcd60e51b8152600401610c3b9061695c565b600e55612549565b61229884848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260128152716d61784e756d4f6643616e6469646174657360701b602082015291506146ee9050565b1561231a57602081146122bd5760405162461bcd60e51b8152600401610c3b90616b54565b604080516020601f84018190048102820181019092528281526000916122fb9185858083850183828082843760009201919091525061474792505050565b600d819055600e5490915081101561231457600d54600e555b50612549565b61237e84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600d81526c6e756d4f66436162696e65747360981b602082015291506146ee9050565b1561242c57602081146123a35760405162461bcd60e51b8152600401610c3b906165f8565b604080516020601f84018190048102820181019092528281526000916123e19185858083850183828082843760009201919091525061474792505050565b9050600081116124035760405162461bcd60e51b8152600401610c3b9061669b565b60298111156124245760405162461bcd60e51b8152600401610c3b906166e3565b600c55612549565b61249684848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601381527266696e616c697479526577617264526174696f60681b602082015291506146ee9050565b1561253157602081146124bb5760405162461bcd60e51b8152600401610c3b90616c3d565b604080516020601f84018190048102820181019092528281526000916124f99185858083850183828082843760009201919091525061474792505050565b90506001811015801561250d575060648111155b6125295760405162461bcd60e51b8152600401610c3b906169cb565b600f55612549565b60405162461bcd60e51b8152600401610c3b90616e71565b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a8484848460405161257e9493929190616481565b60405180910390a150505050565b60046020526000908152604090205481565b68056bc75e2d6310000081565b6001546060906000805b828110156125da576125c681611310565b156125d2578160010191505b6001016125b5565b50606081604051908082528060200260200182016040528015612607578160200160208202803683370190505b5090506000915060005b8381101561268e5761262281611310565b15612686576001818154811061263457fe5b600091825260209091206004909102015482516001600160a01b039091169083908590811061265f57fe5b60200260200101906001600160a01b031690816001600160a01b0316815250508260010192505b600101612611565b50925050505b90565b601581565b61100281565b603281565b60006126b16125ab565b519050600080600c54116126c65760156126ca565b600c545b9050808211156126d8578091505b816126e257600191505b5090565b67016345785d8a000081565b60055481565b61100381565b602981565b60005460ff16156127265760405162461bcd60e51b8152600401610c3b90616c06565b61272e615e41565b60006127546040518061062001604052806105ef8152602001616fe36105ef9139612f13565b91509150806127755760405162461bcd60e51b8152600401610c3b90616d37565b60005b82602001515181101561289a5760018360200151828151811061279757fe5b60209081029190910181015182546001818101855560009485528385208351600493840290910180546001600160a01b039283166001600160a01b03199182161782558587015182850180549185169183169190911790556040860151600283018054606089015160808a01511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b199590981692909516919091179290921694909417161790915560a09093015160039093019290925591860151805191850193918590811061286d57fe5b602090810291909101810151516001600160a01b0316825281019190915260400160002055600101612778565b50506103e8600255506000805460ff19166001179055565b600d5481565b33611001146128d95760405162461bcd60e51b8152600401610c3b90616e98565b600b54612997576128e8615d6b565b60015460005b8181101561299357600b80546001810182556000919091528351600080516020616fa383398151915260169092029182019081556020808601516000805160206175d28339815191528401805460ff191691151591909117905560408601518051879461296f93600080516020616fc3833981519152909101920190615d9a565b5060608201516129859060038301906013615e14565b5050508060010190506128ee565b5050505b60006129a28261474c565b90506129ad81611241565b156129bc576129bc8282614656565b5050565b606581565b3341146129e45760405162461bcd60e51b8152600401610c3b90616dc7565b60005460ff16612a065760405162461bcd60e51b8152600401610c3b9061662d565b60003411612a265760405162461bcd60e51b8152600401610c3b9061692d565b6001600160a01b0381166000908152600460205260409020546007543491906103e89060ff1615612a5657506006545b600083118015612a665750600081115b15612b07576000612a83612710610f9c868563ffffffff613f7f16565b90508015612b055760405161dead9082156108fc029083906000818181858888f19350505050158015612aba573d6000803e3d6000fd5b507f627059660ea01c4733a328effb2294d2f86905bf806da763a89cee254de8bee581604051612aea9190616ef0565b60405180910390a1612b02848263ffffffff613f3d16565b93505b505b8115612c05576000600180840381548110612b1e57fe5b9060005260206000209060040201905080600201601c9054906101000a900460ff1615612b8b57846001600160a01b03167ff177e5d6c5764d79c32883ed824111d9b13f5668cf6ab1cc12dd36791dd955b485604051612b7e9190616ef0565b60405180910390a2612bff565b600354612b9e908563ffffffff613fb916565b6003908155810154612bb6908563ffffffff613fb916565b60038201556040516001600160a01b038616907f93a090ecc682c002995fad3c85b30c5651d7fd29b0be5da9d784a3302aedc05590612bf6908790616ef0565b60405180910390a25b50612c47565b836001600160a01b03167ff177e5d6c5764d79c32883ed824111d9b13f5668cf6ab1cc12dd36791dd955b484604051612c3e9190616ef0565b60405180910390a25b50505050565b600e5481565b61100081565b61dead81565b600b8181548110612c6c57fe5b6000918252602091829020601691909102018054600180830154600280850180546040805161010096831615969096026000190190911692909204601f810188900488028501880190925281845293965060ff90911694919291830182828015612d175780601f10612cec57610100808354040283529160200191612d17565b820191906000526020600020905b815481529060010190602001808311612cfa57829003601f168201915b5050505050905083565b61100481565b6000600a5460001480612d38575081155b80612d435750600954155b15612d5057506000610ea2565b60096000815460019003919050819055506000612d9b600a54610f9c85610f9c600b8981548110612d7d57fe5b6000918252602090912060169091020154439063ffffffff613f3d16565b90506000600b8581548110612dac57fe5b906000526020600020906016020160010160006101000a81548160ff0219169083151502179055506000806110016001600160a01b0316638256ace66040518163ffffffff1660e01b8152600401604080518083038186803b158015612e1157600080fd5b505afa158015612e25573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e4991906161ba565b9150915060009350808310612ec357612e628787613fde565b506040516305bfb49960e41b815261100190635bfb499090612e88908a906004016162f7565b600060405180830381600087803b158015612ea257600080fd5b505af1158015612eb6573d6000803e3d6000fd5b5050505060019350612ed5565b818310612ed557612ed38761474c565b505b6040516001600160a01b038816907fb9d38178dc641ff1817967a63c9078cbcd955a9f1fcd75e0e3636de615d44d3b90600090a25050509392505050565b612f1b615e41565b6000612f25615e41565b612f2d615e65565b612f3e612f39866148ef565b614914565b90506000805b612f4d8361495e565b156130c15780612f7257612f68612f638461497f565b6149cd565b60ff1684526130b9565b80600114156130b4576060612f8e612f898561497f565b614a4d565b90508051604051908082528060200260200182016040528015612fcb57816020015b612fb8615e85565b815260200190600190039081612fb05790505b508560200181905250805160405190808252806020026020018201604052801561300957816020015b6060815260200190600190039081612ff45790505b50604086015260005b81518110156130a957613023615e85565b6060600061304385858151811061303657fe5b6020026020010151614b1e565b92509250925080613063578860009a509a505050505050505050506130ca565b828960200151858151811061307457fe5b6020026020010181905250818960400151858151811061309057fe5b6020026020010181905250505050806001019050613012565b5060019250506130b9565b6130c1565b600101612f44565b50919350909150505b915091565b604080516001808252818301909252606091829190816020015b60608152602001906001900390816130e957905050905061310f8363ffffffff16614c38565b8160008151811061311c57fe5b6020026020010181905250610ea281614c4b565b600060298351111561316757600080516020616f8383398151915260405161315790616740565b60405180910390a15060666113bb565b60005b83518110156132055760005b818110156131fc5784818151811061318a57fe5b6020026020010151600001516001600160a01b03168583815181106131ab57fe5b6020026020010151600001516001600160a01b031614156131f457600080516020616f838339815191526040516131e19061689b565b60405180910390a16066925050506113bb565b600101613176565b5060010161316a565b506060806132138585614cd5565b60015491935091506000908190815b818110156132985767016345785d8a00006001828154811061324057fe5b9060005260206000209060040201600301541061326257836001019350613290565b60006001828154811061327157fe5b9060005260206000209060040201600301541115613290578260010192505b600101613222565b506060836040519080825280602002602001820160405280156132c5578160200160208202803683370190505b5090506060846040519080825280602002602001820160405280156132f4578160200160208202803683370190505b509050606085604051908082528060200260200182016040528015613323578160200160208202803683370190505b509050606086604051908082528060200260200182016040528015613352578160200160208202803683370190505b5090506000606087604051908082528060200260200182016040528015613383578160200160208202803683370190505b5090506060886040519080825280602002602001820160405280156133b2578160200160208202803683370190505b509050600099506000985060006110046001600160a01b031663149d14d96040518163ffffffff1660e01b815260040160206040518083038186803b1580156133fa57600080fd5b505afa15801561340e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061343291906161a2565b905067016345785d8a000081111561347d57600080516020616f8383398151915260405161345f90616bc5565b60405180910390a160689d50505050505050505050505050506113bb565b60005b898110156136ee5767016345785d8a00006001828154811061349e57fe5b9060005260206000209060040201600301541061362357600181815481106134c257fe5b906000526020600020906004020160020160009054906101000a90046001600160a01b0316898d815181106134f357fe5b60200260200101906001600160a01b031690816001600160a01b03168152505060006402540be4006001838154811061352857fe5b9060005260206000209060040201600301548161354157fe5b066001838154811061354f57fe5b9060005260206000209060040201600301540390506135778382613f3d90919063ffffffff16565b898e8151811061358357fe5b6020026020010181815250506001828154811061359c57fe5b906000526020600020906004020160020160009054906101000a90046001600160a01b0316878e815181106135cd57fe5b60200260200101906001600160a01b031690816001600160a01b03168152505081888e815181106135fa57fe5b6020908102919091010152613615868263ffffffff613fb916565b95508c6001019c50506136e6565b60006001828154811061363257fe5b90600052602060002090600402016003015411156136e6576001818154811061365757fe5b906000526020600020906004020160010160009054906101000a90046001600160a01b0316848c8151811061368857fe5b60200260200101906001600160a01b031690816001600160a01b031681525050600181815481106136b557fe5b906000526020600020906004020160030154838c815181106136d357fe5b6020026020010181815250508a6001019a505b600101613480565b5060008415613964576002546040516303702b2960e51b815261100491636e056520918891613728918e918e918d914201906004016163e9565b6020604051808303818588803b15801561374157600080fd5b505af193505050508015613772575060408051601f3d908101601f1916820190925261376f9181019061610e565b60015b6138e9576040516000815260443d101561378e57506000613829565b60046000803e60005160e01c6308c379a081146137af576000915050613829565b60043d036004833e81513d60248201116001600160401b03821117156137da57600092505050613829565b80830180516001600160401b038111156137fb576000945050505050613829565b8060208301013d860181111561381957600095505050505050613829565b601f01601f191660405250925050505b806138345750613876565b60019150857fa7cdeed7d0db45e3219a6e5d60838824c16f1d39991fcfe3f963029c844bf28082604051613868919061646e565b60405180910390a2506138e4565b3d8080156138a0576040519150601f19603f3d011682016040523d82523d6000602084013e6138a5565b606091505b5060019150857fbfa884552dd8921b6ce90bfe906952ae5b3b29be0cc1a951d4f62697635a3a45826040516138da919061646e565b60405180910390a2505b613964565b801561392b577fa217d08e65f80c73121cd9db834d81652d544bfbf452f6d04922b16c90a37b708660405161391e9190616ef0565b60405180910390a1613962565b857fa7cdeed7d0db45e3219a6e5d60838824c16f1d39991fcfe3f963029c844bf28060405161395990616530565b60405180910390a25b505b8015613b1a5760005b8751811015613b1857600088828151811061398457fe5b6020026020010151905060006001828154811061399d57fe5b60009182526020909120600160049092020181015481546001600160a01b03909116916108fc91859081106139ce57fe5b9060005260206000209060040201600301549081150290604051600060405180830381858888f1935050505090508015613a8a5760018281548110613a0f57fe5b60009182526020909120600160049092020181015481546001600160a01b03909116917f6c61d60f69a7beb3e1c80db7f39f37b208537cbb19da3174511b477812b2fc7d9185908110613a5e57fe5b906000526020600020906004020160030154604051613a7d9190616ef0565b60405180910390a2613b0e565b60018281548110613a9757fe5b60009182526020909120600160049092020181015481546001600160a01b03909116917f25d0ce7d2f0cec669a8c17efe49d195c13455bb8872b65fa610ac7f53fe4ca7d9185908110613ae657fe5b906000526020600020906004020160030154604051613b059190616ef0565b60405180910390a25b505060010161396d565b505b835115613c645760005b8451811015613c62576000858281518110613b3b57fe5b60200260200101516001600160a01b03166108fc868481518110613b5b57fe5b60200260200101519081150290604051600060405180830381858888f1935050505090508015613bf157858281518110613b9157fe5b60200260200101516001600160a01b03167f6c61d60f69a7beb3e1c80db7f39f37b208537cbb19da3174511b477812b2fc7d868481518110613bcf57fe5b6020026020010151604051613be49190616ef0565b60405180910390a2613c59565b858281518110613bfd57fe5b60200260200101516001600160a01b03167f25d0ce7d2f0cec669a8c17efe49d195c13455bb8872b65fa610ac7f53fe4ca7d868481518110613c3b57fe5b6020026020010151604051613c509190616ef0565b60405180910390a25b50600101613b24565b505b5050505050505050505050506000471115613ce0577f6ecc855f9440a9282c90913bbc91619fd44f5ec0b462af28d127b116f130aa4d47604051613ca89190616ef0565b60405180910390a1604051611002904780156108fc02916000818181858888f19350505050158015613cde573d6000803e3d6000fd5b505b60006003819055600555815115613cfb57613cfb8282614f0e565b6110016001600160a01b031663fc4333cd6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015613d3857600080fd5b505af1158015613d4c573d6000803e3d6000fd5b50506040517fedd8d7296956dd970ab4de3f2fc03be2b0ffc615d20cd4c72c6e44f928630ebf925060009150a1506000949350505050565b80516001600160a01b0316600090815260046020526040812054801580613dd55750600180820381548110613db557fe5b9060005260206000209060040201600201601c9054906101000a900460ff165b15613e1b5782516040516001600160a01b03909116907fe209c46bebf57cf265d5d9009a00870e256d9150f3ed5281ab9d9eb3cec6e4be90600090a2600091505061130b565b600154600554600019820111801590613e715784516040516001600160a01b03909116907fe209c46bebf57cf265d5d9009a00870e256d9150f3ed5281ab9d9eb3cec6e4be90600090a26000935050505061130b565b600580546001908101909155805481906000198601908110613e8f57fe5b6000918252602082206002600490920201018054921515600160e01b0260ff60e01b199093169290921790915585516040516001600160a01b03909116917ff226e7d8f547ff903d9d419cf5f54e0d7d07efa9584135a53a057c5f1f27f49a91a2506000949350505050565b6000610ea283836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506156ed565b6000610ea283836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250615724565b600082613f8e575060006113bb565b82820282848281613f9b57fe5b0414610ea25760405162461bcd60e51b8152600401610c3b90616ac5565b600082820183811015610ea25760405162461bcd60e51b8152600401610c3b90616664565b60008060018381548110613fee57fe5b906000526020600020906004020160030154905060006001808054905003905060016140186125ab565b511161404d5760006001858154811061402d57fe5b9060005260206000209060040201600301819055506000925050506113bb565b846001600160a01b03167f3b6f9ef90462b512a1293ecec018670bf7b7f1876fb727590a8a6d7643130a70836040516140869190616ef0565b60405180910390a26001600160a01b038516600090815260046020526040812055835b6001546000190181101561427357600181600101815481106140c757fe5b9060005260206000209060040201600182815481106140e257fe5b60009182526020909120825460049092020180546001600160a01b03199081166001600160a01b0393841617825560018085015481840180548416918616919091179055600280860180549185018054909416919095161780835584546001600160401b03600160a01b91829004160267ffffffffffffffff60a01b1990911617808355935460ff600160e01b918290041615150260ff60e01b19909416939093179055600392830154920191909155600b8054909183019081106141a357fe5b9060005260206000209060160201600b82815481106141be57fe5b600091825260209091208254601690920201908155600180830154818301805460ff909216151560ff1990921691909117905560028084018054614215938386019390821615610100026000190190911604615eba565b5061422860038281019084016013615f2f565b5090505080600101600460006001848154811061424157fe5b600091825260208083206004909202909101546001600160a01b031683528201929092526040019020556001016140a9565b50600180548061427f57fe5b60008281526020812060046000199093019283020180546001600160a01b0319908116825560018201805490911690556002810180546001600160e81b0319169055600301559055600b8054806142d257fe5b60008281526020812060166000199093019283020181815560018101805460ff19169055906143046002830182615f59565b614312600383016000615f9d565b50509055600081838161432157fe5b04905080156143855760015460005b8181101561438257826001828154811061434657fe5b906000526020600020906004020160030154016001828154811061436657fe5b6000918252602090912060036004909202010155600101614330565b50505b50600195945050505050565b6001548151604080518281526020808402820101909152606092919083908280156143d057816020015b60608152602001906001900390816143bb5790505b50600b5490915083146143e757925061130b915050565b60005b828110156144f657600b60016004600089858151811061440657fe5b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002054038154811061443a57fe5b600091825260209182902060026016909202018101805460408051601f6000196101006001861615020190931694909404918201859004850284018501905280835291929091908301828280156144d25780601f106144a7576101008083540402835291602001916144d2565b820191906000526020600020905b8154815290600101906020018083116144b557829003601f168201915b50505050508282815181106144e357fe5b60209081029190910101526001016143ea565b50949350505050565b60005b8281101561464c57600082878388016040516020016145229291906162e9565b6040516020818303038152906040528051906020012060001c8161454257fe5b06905080850182870114614643576000898388018151811061456057fe5b602002602001015190506060898489018151811061457a57fe5b602002602001015190508a8388018151811061459257fe5b60200260200101518b858a01815181106145a857fe5b60200260200101906001600160a01b031690816001600160a01b031681525050818b848901815181106145d757fe5b60200260200101906001600160a01b031690816001600160a01b031681525050898388018151811061460557fe5b60200260200101518a858a018151811061461b57fe5b6020026020010181905250808a8489018151811061463557fe5b602002602001018190525050505b50600101614502565b5050505050505050565b600980546001908101909155600b80548390811061467057fe5b906000526020600020906016020160010160006101000a81548160ff02191690831515021790555043600b82815481106146a657fe5b600091825260208220601690910201919091556040516001600160a01b038416917ff62981a567ec3cec866c6fa93c55bcdf841d6292d18b8d522ececa769375d82d91a25050565b60008160405160200161470191906162cd565b604051602081830303815290604052805190602001208360405160200161472891906162cd565b6040516020818303038152906040528051906020012014905092915050565b015190565b6001600160a01b038116600090815260046020526040812054806147755750600019905061130b565b60018103905060006001828154811061478a57fe5b90600052602060002090600402016003015490506000600183815481106147ad57fe5b6000918252602090912060036004909202010155600154604051600019909101906001600160a01b038616907f8cd4e147d8af98a9e3b6724021b8bf6aed2e5dac71c38f2dce8161b82585b25d90614806908590616ef0565b60405180910390a28061481e5782935050505061130b565b600081838161482957fe5b04905080156148e55760005b8481101561488757816001828154811061484b57fe5b906000526020600020906004020160030154016001828154811061486b57fe5b6000918252602090912060036004909202010155600101614835565b50600180549085015b818110156148e25782600182815481106148a657fe5b90600052602060002090600402016003015401600182815481106148c657fe5b6000918252602090912060036004909202010155600101614890565b50505b5091949350505050565b6148f7615fac565b506040805180820190915281518152602082810190820152919050565b61491c615e65565b61492582615750565b61492e57600080fd5b600061493d836020015161578a565b60208085015160408051808201909152868152920190820152915050919050565b6000614968615fac565b505080518051602091820151919092015191011190565b614987615fac565b6149908261495e565b61499957600080fd5b602082015160006149a9826157ed565b80830160209586015260408051808201909152908152938401919091525090919050565b8051600090158015906149e257508151602110155b6149eb57600080fd5b60006149fa836020015161578a565b90508083600001511015614a205760405162461bcd60e51b8152600401610c3b90616c83565b8251602080850151830180519284900392918310156144f657506020919091036101000a90049392505050565b6060614a5882615750565b614a6157600080fd5b6000614a6c836158ce565b9050606081604051908082528060200260200182016040528015614aaa57816020015b614a97615fac565b815260200190600190039081614a8f5790505b5090506000614abc856020015161578a565b60208601510190506000805b84811015614b1357614ad9836157ed565b9150604051806040016040528083815260200184815250848281518110614afc57fe5b602090810291909101015291810191600101614ac8565b509195945050505050565b614b26615e85565b60606000614b32615e85565b6060614b3c615e65565b614b4587614914565b90506000805b614b548361495e565b15614c295780614b7f57614b6f614b6a8461497f565b61592a565b6001600160a01b03168552614c21565b8060011415614ba757614b94614b6a8461497f565b6001600160a01b03166020860152614c21565b8060021415614bcf57614bbc614b6a8461497f565b6001600160a01b03166040860152614c21565b8060031415614bfb57614be4612f638461497f565b6001600160401b0316606086015260019150614c21565b8060041415614c1c57614c15614c108461497f565b615944565b9350614c21565b614c29565b600101614b4b565b50929791965091945092505050565b60606113bb614c46836159b4565b615a9a565b6060815160001415614c6c575060408051600081526020810190915261130b565b606082600081518110614c7b57fe5b602002602001015190506000600190505b8351811015614cbc57614cb282858381518110614ca557fe5b6020026020010151615aec565b9150600101614c8c565b50610ea2614ccf825160c060ff16615b69565b82615aec565b606080600080808080614ce66126a7565b6001549091505b8015614df457600181039250600b8381548110614d0657fe5b600091825260209091206001601690920201015460ff16614d2657614deb565b60018381548110614d3357fe5b60009182526020909120600490910201546001600160a01b03169450614d5a858484612d27565b9350831580614d6d575060018a51038610155b15614d7757614deb565b60005b8a51811015614de957856001600160a01b03168b8281518110614d9957fe5b6020026020010151600001516001600160a01b03161415614de15760018b8281518110614dc257fe5b6020908102919091010151901515608090910152600190960195614de9565b600101614d7a565b505b60001901614ced565b5084895103604051908082528060200260200182016040528015614e3257816020015b614e1f615e85565b815260200190600190039081614e175790505b50965084895103604051908082528060200260200182016040528015614e6c57816020015b6060815260200190600190039081614e575790505b5095506000915060005b8951811015614f0057898181518110614e8b57fe5b602002602001015160800151614ef857898181518110614ea757fe5b6020026020010151888481518110614ebb57fe5b6020026020010181905250888181518110614ed257fe5b6020026020010151878481518110614ee657fe5b60200260200101819052508260010192505b600101614e76565b5050505050505b9250929050565b600154825160005b8281101561502b576001614f28615e85565b60018381548110614f3557fe5b600091825260208083206040805160c08101825260049490940290910180546001600160a01b0390811685526001820154811693850193909352600281015492831691840191909152600160a01b82046001600160401b03166060840152600160e01b90910460ff16151560808301526003015460a082015291505b84811015614fff57878181518110614fc557fe5b6020026020010151600001516001600160a01b031682600001516001600160a01b03161415614ff75760009250614fff565b600101614fb1565b5081156150215780516001600160a01b03166000908152600460205260408120555b5050600101614f16565b50808211156150ea57805b828110156150e857600180548061504957fe5b60008281526020812060046000199093019283020180546001600160a01b0319908116825560018201805490911690556002810180546001600160e81b0319169055600301559055600b80548061509c57fe5b60008281526020812060166000199093019283020181815560018101805460ff19169055906150ce6002830182615f59565b6150dc600383016000615f9d565b50509055600101615036565b505b60008183106150f957816150fb565b825b905060005b8181101561549f576151ad86828151811061511757fe5b60200260200101516001838154811061512c57fe5b60009182526020918290206040805160c08101825260049390930290910180546001600160a01b0390811684526001820154811694840194909452600281015493841691830191909152600160a01b83046001600160401b03166060830152600160e01b90920460ff161515608082015260039091015460a0820152615c3b565b6153615780600101600460008884815181106151c557fe5b6020026020010151600001516001600160a01b03166001600160a01b031681526020019081526020016000208190555085818151811061520157fe5b60200260200101516001828154811061521657fe5b6000918252602091829020835160049092020180546001600160a01b039283166001600160a01b0319918216178255928401516001820180549184169185169190911790556040840151600282018054606087015160808801511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b1995909716929097169190911792909216939093171692909217905560a09091015160039091015584518590829081106152d157fe5b6020026020010151600b82815481106152e657fe5b9060005260206000209060160201600201908051906020019061530a929190615d9a565b506000600b828154811061531a57fe5b60009182526020822060169190910201600101805460ff191692151592909217909155600b80548390811061534b57fe5b6000918252602090912060169091020155615497565b61542785828151811061537057fe5b6020026020010151600b838154811061538557fe5b600091825260209182902060026016909202018101805460408051601f60001961010060018616150201909316949094049182018590048502840185019052808352919290919083018282801561541d5780601f106153f25761010080835404028352916020019161541d565b820191906000526020600020905b81548152906001019060200180831161540057829003601f168201915b5050505050615cbc565b6154725784818151811061543757fe5b6020026020010151600b828154811061544c57fe5b90600052602060002090601602016002019080519060200190615470929190615d9a565b505b60006001828154811061548157fe5b9060005260206000209060040201600301819055505b600101615100565b5082821115615677576154b0615d6b565b835b83811015615674578581815181106154c657fe5b6020026020010151826040018190525060018782815181106154e457fe5b6020908102919091018101518254600181810185556000948552838520835160049093020180546001600160a01b039384166001600160a01b0319918216178255848601518284018054918616918316919091179055604080860151600284018054606089015160808a01511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b1995909a1692909616919091179290921696909617169190911790935560a090930151600390930192909255600b8054928301815590935284516016909102600080516020616fa38339815191528101918255858301516000805160206175d28339815191528201805491151560ff199092169190911790559285015180518694929361561a93600080516020616fc383398151915201920190615d9a565b5060608201516156309060038301906013615e14565b505050806001016004600089848151811061564757fe5b602090810291909101810151516001600160a01b03168252810191909152604001600020556001016154b2565b50505b6000600981905560015493505b838110156156e5576000600b828154811061569b57fe5b60009182526020822060169190910201600101805460ff191692151592909217909155600b8054839081106156cc57fe5b6000918252602090912060169091020155600101615684565b505050505050565b6000818361570e5760405162461bcd60e51b8152600401610c3b919061646e565b50600083858161571a57fe5b0495945050505050565b600081848411156157485760405162461bcd60e51b8152600401610c3b919061646e565b505050900390565b80516000906157615750600061130b565b6020820151805160001a9060c08210156157805760009250505061130b565b5060019392505050565b8051600090811a60808110156157a457600091505061130b565b60b88110806157bf575060c081108015906157bf575060f881105b156157ce57600191505061130b565b60c08110156157e25760b51901905061130b565b60f51901905061130b565b80516000908190811a608081101561580857600191506158c7565b60b881101561581d57607e19810191506158c7565b60c081101561586e57600060b78203600186019550806020036101000a8651049150600181018201935050808310156158685760405162461bcd60e51b8152600401610c3b90616a12565b506158c7565b60f88110156158835760be19810191506158c7565b600060f78203600186019550806020036101000a8651049150600181018201935050808310156158c55760405162461bcd60e51b8152600401610c3b90616a12565b505b5092915050565b80516000906158df5750600061130b565b600080905060006158f3846020015161578a565b602085015185519181019250015b8082101561592157615912826157ed565b82019150826001019250615901565b50909392505050565b805160009060151461593b57600080fd5b6113bb826149cd565b805160609061595257600080fd5b6000615961836020015161578a565b83516040805191839003808352601f19601f8201168301602001909152919250606090828015615998576020820181803683370190505b50905060008160200190506144f6848760200151018285615d20565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff1984166159f857506018615a1c565b6fffffffffffffffffffffffffffffffff198416615a1857506010615a1c565b5060005b6020811015615a5257818181518110615a3157fe5b01602001516001600160f81b03191615615a4a57615a52565b600101615a1c565b60008160200390506060816040519080825280601f01601f191660200182016040528015615a87576020820181803683370190505b5080830196909652508452509192915050565b606081516001148015615acc5750607f60f81b82600081518110615aba57fe5b01602001516001600160f81b03191611155b15615ad857508061130b565b6113bb615aea8351608060ff16615b69565b835b6060806040519050835180825260208201818101602087015b81831015615b1d578051835260209283019201615b05565b50855184518101855292509050808201602086015b81831015615b4a578051835260209283019201615b32565b508651929092011591909101601f01601f191660405250905092915050565b6060680100000000000000008310615b935760405162461bcd60e51b8152600401610c3b90616816565b60408051600180825281830190925260609160208201818036833701905050905060378411615bed5782840160f81b81600081518110615bcf57fe5b60200101906001600160f81b031916908160001a90535090506113bb565b6060615bf8856159b4565b90508381510160370160f81b82600081518110615c1157fe5b60200101906001600160f81b031916908160001a905350615c328282615aec565b95945050505050565b805182516000916001600160a01b039182169116148015615c75575081602001516001600160a01b031683602001516001600160a01b0316145b8015615c9a575081604001516001600160a01b031683604001516001600160a01b0316145b8015610ea25750506060908101519101516001600160401b0390811691161490565b815181516000916001918114808314615cd85760009250615d16565b600160208701838101602088015b600284838510011415615d11578051835114615d055760009650600093505b60209283019201615ce6565b505050505b5090949350505050565b80615d2a57610c5b565b5b60208110615d4a578251825260209283019290910190601f1901615d2b565b915181516020939093036101000a6000190180199091169216919091179052565b60405180608001604052806000815260200160001515815260200160608152602001615d95615fc6565b905290565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10615ddb57805160ff1916838001178555615e08565b82800160010185558215615e08579182015b82811115615e08578251825591602001919060010190615ded565b506126e2929150615fe5565b8260138101928215615e085791602002820182811115615e08578251825591602001919060010190615ded565b6040518060600160405280600060ff16815260200160608152602001606081525090565b6040518060400160405280615e78615fac565b8152602001600081525090565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a081019190915290565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10615ef35780548555615e08565b82800160010185558215615e0857600052602060002091601f016020900482015b82811115615e08578254825591600101919060010190615f14565b8260138101928215615e085791820182811115615e08578254825591600101919060010190615f14565b50805460018160011615610100020316600290046000825580601f10615f7f5750611517565b601f0160209004906000526020600020908101906115179190615fe5565b50611517906013810190615fe5565b604051806040016040528060008152602001600081525090565b6040518061026001604052806013906020820280368337509192915050565b61269491905b808211156126e25760008155600101615feb565b60008083601f840112616010578182fd5b5081356001600160401b03811115616026578182fd5b6020830191508360208083028501011115614f0757600080fd5b60008083601f840112616051578182fd5b5081356001600160401b03811115616067578182fd5b602083019150836020828501011115614f0757600080fd5b600060208284031215616090578081fd5b81356001600160a01b0381168114610ea2578182fd5b600080600080604085870312156160bb578283fd5b84356001600160401b03808211156160d1578485fd5b6160dd88838901615fff565b909650945060208701359150808211156160f5578384fd5b5061610287828801615fff565b95989497509550505050565b60006020828403121561611f578081fd5b81518015158114610ea2578182fd5b60008060008060408587031215616143578384fd5b84356001600160401b0380821115616159578586fd5b61616588838901616040565b9096509450602087013591508082111561617d578384fd5b5061610287828801616040565b60006020828403121561619b578081fd5b5035919050565b6000602082840312156161b3578081fd5b5051919050565b600080604083850312156161cc578182fd5b505080516020909101519092909150565b6000806000604084860312156161f1578283fd5b833560ff81168114616201578384fd5b925060208401356001600160401b0381111561621b578283fd5b61622786828701616040565b9497909650939450505050565b6000815180845260208085019450808401835b8381101561626c5781516001600160a01b031687529582019590820190600101616247565b509495945050505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b600081518084526162b9816020860160208601616f56565b601f01601f19169290920160200192915050565b600082516162df818460208701616f56565b9190910192915050565b918252602082015260400190565b6001600160a01b0391909116815260200190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b03968716815294861660208601529290941660408401526001600160401b03166060830152911515608082015260a081019190915260c00190565b600060208252610ea26020830184616234565b60006040825261638c6040830185616234565b602083820381850152818551808452828401915082838202850101838801865b838110156163da57601f198784030185526163c88383516162a1565b948601949250908501906001016163ac565b50909998505050505050505050565b6000608082526163fc6080830187616234565b828103602084810191909152865180835287820192820190845b8181101561643257845183529383019391830191600101616416565b505084810360408601526164468188616234565b93505050506001600160401b038316606083015295945050505050565b901515815260200190565b600060208252610ea260208301846162a1565b600060408252616495604083018688616277565b82810360208401526164a8818587616277565b979650505050505050565b6020808252601c908201527f6c656e677468206f66206275726e526174696f206d69736d6174636800000000604082015260600190565b60208082526026908201527f6c656e677468206f66206d61784e756d4f664d61696e7461696e696e67206d696040820152650e6dac2e8c6d60d31b606082015260800190565b6020808252601b908201527f6261746368207472616e736665722072657475726e2066616c73650000000000604082015260600190565b6020808252602c908201527f6c656e677468206f66206d61784e756d4f66576f726b696e6743616e6469646160408201526b0e8cae640dad2e6dac2e8c6d60a31b606082015260800190565b60208082526025908201527f6c656e677468206f66206d61696e7461696e536c6173685363616c65206d69736040820152640dac2e8c6d60db1b606082015260800190565b6020808252818101527f6c656e677468206f66206e756d4f66436162696e657473206d69736d61746368604082015260600190565b60208082526019908201527f74686520636f6e7472616374206e6f7420696e69742079657400000000000000604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b60208082526028908201527f746865206e756d4f66436162696e657473206d75737420626520677265617465604082015267072207468616e20360c41b606082015260800190565b60208082526039908201527f746865206e756d4f66436162696e657473206d757374206265206c657373207460408201527f68616e204d41585f4e554d5f4f465f56414c494441544f525300000000000000606082015260800190565b60208082526029908201527f746865206e756d626572206f662076616c696461746f727320657863656564206040820152681d1a19481b1a5b5a5d60ba1b606082015260800190565b60208082526022908201527f63616e206e6f7420646f207468697320747769636520696e206f6e6520626c6f604082015261636b60f01b606082015260800190565b6020808252602b908201527f746865206275726e526174696f206d757374206265206e6f206772656174657260408201526a0207468616e2031303030360ac1b606082015260800190565b6020808252600e908201526d696e70757420746f6f206c6f6e6760901b604082015260600190565b60208082526037908201527f746865206d61784e756d4f664d61696e7461696e696e67206d7573742062652060408201527f6c657373207468616e206e756d4f66436162696e657473000000000000000000606082015260800190565b6020808252602b908201527f6475706c696361746520636f6e73656e7375732061646472657373206f66207660408201526a185b1a59185d1bdc94d95d60aa1b606082015260800190565b60208082526027908201527f7468652065787069726554696d655365636f6e64476170206973206f7574206f604082015266662072616e676560c81b606082015260800190565b6020808252601590820152746465706f7369742076616c7565206973207a65726f60581b604082015260600190565b60208082526049908201527f746865206d61784e756d4f66576f726b696e6743616e64696461746573206d7560408201527f7374206265206e6f742067726561746572207468616e206d61784e756d4f6643606082015268616e6469646174657360b81b608082015260a00190565b60208082526027908201527f7468652066696e616c697479526577617264526174696f206973206f7574206f604082015266662072616e676560c81b606082015260800190565b6020808252601190820152706164646974696f6e206f766572666c6f7760781b604082015260600190565b60208082526023908201527f63616e206e6f7420656e7465722054656d706f72617279204d61696e74656e616040820152626e636560e81b606082015260800190565b60208082526025908201527f6c656e677468206f66206a61696c2076616c696461746f7273206d757374206260408201526465206f6e6560d81b606082015260800190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252602e908201527f746865206d6573736167652073656e646572206d75737420626520676f76657260408201526d1b985b98d94818dbdb9d1c9858dd60921b606082015260800190565b60208082526025908201527f6c656e677468206f66206d61784e756d4f6643616e64696461746573206d69736040820152640dac2e8c6d60db1b606082015260800190565b6020808252601290820152716e6f7420696e206d61696e74656e616e636560701b604082015260600190565b60208082526021908201527f666565206973206c6172676572207468616e2044555354595f494e434f4d494e6040820152604760f81b606082015260800190565b60208082526019908201527f74686520636f6e747261637420616c726561647920696e697400000000000000604082015260600190565b60208082526026908201527f6c656e677468206f662066696e616c697479526577617264526174696f206d696040820152650e6dac2e8c6d60d31b606082015260800190565b6020808252601a908201527f6c656e677468206973206c657373207468616e206f6666736574000000000000604082015260600190565b60208082526026908201527f6c656e677468206f662065787069726554696d655365636f6e64476170206d696040820152650e6dac2e8c6d60d31b606082015260800190565b60208082526017908201527f6f6e6c792063757272656e742076616c696461746f7273000000000000000000604082015260600190565b60208082526021908201527f6661696c656420746f20706172736520696e69742076616c696461746f7253656040820152601d60fa1b606082015260800190565b6020808252602f908201527f746865206d6573736167652073656e646572206d7573742062652063726f737360408201526e0818da185a5b8818dbdb9d1c9858dd608a1b606082015260800190565b6020808252602d908201527f746865206d6573736167652073656e646572206d75737420626520746865206260408201526c3637b1b590383937b23ab1b2b960991b606082015260800190565b6020808252603e908201527f746865206d61696e7461696e536c6173685363616c65206d757374206265206760408201527f726561746572207468616e203020616e64206c657373207468616e2031300000606082015260800190565b6020808252600d908201526c756e6b6e6f776e20706172616d60981b604082015260600190565b60208082526029908201527f746865206d6573736167652073656e646572206d75737420626520736c6173686040820152680818dbdb9d1c9858dd60ba1b606082015260800190565b61ffff91909116815260200190565b90815260200190565b6000848252831515602083015260606040830152615c3260608301846162a1565b63ffffffff91909116815260200190565b60ff91909116815260200190565b600060ff8516825260406020830152615c32604083018486616277565b60005b83811015616f71578181015183820152602001616f59565b83811115612c47575050600091015256fe70e72399380dcfb0338abc03dc8d47f9f470ada8e769c9a78d644ea97385ecb20175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db90175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01dbbf905ec80f905e8f846942a7cdd959bfe8d9487b2a43b33565295a698f7e294b6a7edd747c0554875d3fc531d19ba1497992c5e941ff80f3f7f110ffd8920a3ac38fdef318fe94a3f86048c27395000f846946488aa4d1955ee33403f8ccb1d4de5fb97c7ade294220f003d8bdfaadf52aa1e55ae4cc485e6794875941a87e90e440a39c99aa9cb5cea0ad6a3f0b2407b86048c27395000f846949ef9f4360c606c7ab4db26b016007d3ad0ab86a0946103af86a874b705854033438383c82575f25bc29418e2db06cbff3e3c5f856410a1838649e760175786048c27395000f84694ee01c3b1283aa067c58eab4709f85e99d46de5fe94ee4b9bfb1871c64e2bcabb1dc382dc8b7c4218a29415904ab26ab0e99d70b51c220ccdcccabee6e29786048c27395000f84694685b1ded8013785d6623cc18d214320b6bb6475994a20ef4e5e4e7e36258dbf51f4d905114cb1b34bc9413e39085dc88704f4394d35209a02b1a9520320c86048c27395000f8469478f3adfc719c99674c072166708589033e2d9afe9448a30d5eaa7b64492a160f139e2da2800ec3834e94055838358c29edf4dcc1ba1985ad58aedbb6be2b86048c27395000f84694c2be4ec20253b8642161bc3f444f53679c1f3d479466f50c616d737e60d7ca6311ff0d9c434197898a94d1d678a2506eeaa365056fe565df8bc8659f28b086048c27395000f846942f7be8361c80a4c1e7e9aaf001d0877f1cfde218945f93992ac37f3e61db2ef8a587a436a161fd210b94ecbc4fb1a97861344dad0867ca3cba2b860411f086048c27395000f84694ce2fd7544e0b2cc94692d4a704debef7bcb613289444abc67b4b2fba283c582387f54c9cba7c34bafa948acc2ab395ded08bb75ce85bf0f95ad2abc51ad586048c27395000f84694b8f7166496996a7da21cf1f1b04d9b3e26a3d077946770572763289aac606e4f327c2f6cc1aa3b3e3b94882d745ed97d4422ca8da1c22ec49d880c4c097286048c27395000f846942d4c407bbe49438ed859fe965b140dcf1aab71a9943ad0939e120f33518fbba04631afe7a3ed6327b194b2bbb170ca4e499a2b0f3cc85ebfa6e8c4dfcbea86048c27395000f846946bbad7cf34b5fa511d8e963dbba288b1960e75d694853b0f6c324d1f4e76c8266942337ac1b0af1a229442498946a51ca5924552ead6fc2af08b94fcba648601d1a94a2000f846944430b3230294d12c6ab2aac5c2cd68e80b16b581947b107f4976a252a6939b771202c28e64e03f52d694795811a7f214084116949fc4f53cedbf189eeab28601d1a94a2000f84694ea0a6e3c511bbd10f4519ece37dc24887e11b55d946811ca77acfb221a49393c193f3a22db829fcc8e9464feb7c04830dd9ace164fc5c52b3f5a29e5018a8601d1a94a2000f846947ae2f5b9e386cd1b50a4550696d957cb4900f03a94e83bcc5077e6b873995c24bac871b5ad856047e19464e48d4057a90b233e026c1041e6012ada897fe88601d1a94a2000f8469482012708dafc9e1b880fd083b32182b869be8e09948e5adc73a2d233a1b496ed3115464dd6c7b887509428b383d324bc9a37f4e276190796ba5a8947f5ed8601d1a94a2000f8469422b81f8e175ffde54d797fe11eb03f9e3bf75f1d94a1c3ef7ca38d8ba80cce3bfc53ebd2903ed21658942767f7447f7b9b70313d4147b795414aecea54718601d1a94a2000f8469468bf0b8b6fb4e317a0f9d6f03eaf8ce6675bc60d94675cfe570b7902623f47e7f59c9664b5f5065dcf94d84f0d2e50bcf00f2fc476e1c57f5ca2d57f625b8601d1a94a2000f846948c4d90829ce8f72d0163c1d5cf348a862d5506309485c42a7b34309bee2ed6a235f86d16f059deec5894cc2cedc53f0fa6d376336efb67e43d167169f3b78601d1a94a2000f8469435e7a025f4da968de7e4d7e4004197917f4070f194b1182abaeeb3b4d8eba7e6a4162eac7ace23d57394c4fd0d870da52e73de2dd8ded19fe3d26f43a1138601d1a94a2000f84694d6caa02bbebaebb5d7e581e4b66559e635f805ff94c07335cf083c1c46a487f0325769d88e163b653694efaff03b42e41f953a925fc43720e45fb61a19938601d1a94a20000175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01dbaa26469706673582212206cf6e773ca0b0d999abe4e586cd00abd836c1f2e74f76626269d55c8fc09634364736f6c63430006040033", + }, + { + ContractAddr: common.HexToAddress(SlashContract), + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/b144718e94d7a1ebb24a7103202300f08826f369", + Code: "608060405234801561001057600080fd5b506004361061027f5760003560e01c80637942fd051161015c578063c80d4b8f116100ce578063dc927faf11610087578063dc927faf146104ad578063e1c7392a146104b5578063f9a2bbc7146104bd578063fc3e5908146104c5578063fc4333cd146104cd578063fd6a6879146104d55761027f565b8063c80d4b8f1461045c578063c81b166214610464578063c8509d811461046c578063c96be4cb1461047f578063cc844b7314610492578063d2a42e4b146104a55761027f565b80639dc09262116101205780639dc0926214610421578063a1a11bf514610429578063a78abc1614610431578063ab51bb9614610439578063ac0af62914610441578063ac431751146104495761027f565b80637942fd05146103ee5780638256ace6146103f6578063831d65d1146103fe57806396713da9146104115780639bc8e4f2146104195761027f565b8063493279b1116101f557806362b72cf5116101b957806362b72cf5146103be5780636e47b482146103c657806370fd5bad146103ce578063718a8aa8146103d657806375d47a0a146103de5780637912a65d146103e65761027f565b8063493279b11461037c5780634bf6c8821461039157806351e8067214610399578063567a372d146103a15780635bfb4990146103a95761027f565b806335aa2e441161024757806335aa2e441461030e57806337c8dab914610321578063389f4f71146103425780633a63f4b1146103575780633dffc3871461035f57806343756e5c146103745761027f565b80630bee7a67146102845780630e2374a5146102a25780631182b875146102b757806322d1e80b146102d757806323bac5a2146102ec575b600080fd5b61028c6104dd565b60405161029991906132a4565b60405180910390f35b6102aa6104e2565b6040516102999190612b82565b6102ca6102c5366004612ab8565b6104e8565b6040516102999190612bba565b6102df61054e565b6040516102999190612baf565b6102ff6102fa366004612866565b610557565b6040516102999392919061328c565b6102aa61031c366004612a88565b61057a565b61033461032f366004612866565b6105a1565b60405161029992919061327e565b61034a6105f8565b6040516102999190613254565b61034a6105fe565b610367610604565b60405161029991906132b5565b6102aa610609565b61038461060f565b6040516102999190613245565b610367610614565b6102aa610619565b61034a61061f565b6103bc6103b7366004612866565b610625565b005b61034a6106d0565b6102aa6106d6565b6103676106dc565b6103676106e1565b6102aa6106e6565b61034a6106ec565b6103676106f1565b6103346106f6565b6103bc61040c366004612ab8565b610700565b610367610812565b61034a610817565b6102aa610822565b6102aa610828565b6102df61082e565b61028c610837565b61034a61083c565b6103bc61045736600461296c565b610841565b61034a610ce0565b6102aa610ce5565b6103bc61047a366004612ab8565b610ceb565b6103bc61048d366004612866565b610d5c565b6103bc6104a03660046129d5565b61114d565b61034a61169a565b6102aa61169f565b6103bc6116a5565b6102aa6116e1565b6103676116e7565b6103bc6116ec565b6102aa611b35565b606481565b61200181565b606033612000146105145760405162461bcd60e51b815260040161050b906130cb565b60405180910390fd5b60005460ff166105365760405162461bcd60e51b815260040161050b90612c9b565b60405162461bcd60e51b815260040161050b9061318e565b60075460ff1681565b600260208190526000918252604090912080546001820154919092015460ff1683565b6001818154811061058757fe5b6000918252602090912001546001600160a01b0316905081565b6000806105ac61264d565b5050506001600160a01b0316600090815260026020818152604092839020835160608101855281548082526001830154938201849052919093015460ff16151592909301919091529091565b60055481565b60065481565b600181565b61100181565b603881565b600881565b61200081565b60045481565b33611000146106465760405162461bcd60e51b815260040161050b90612edf565b60005460ff166106685760405162461bcd60e51b815260040161050b90612c9b565b61200063f7a251d7600b61067b84611b3b565b60006040518463ffffffff1660e01b815260040161069b939291906132c3565b600060405180830381600087803b1580156106b557600080fd5b505af11580156106c9573d6000803e3d6000fd5b5050505050565b60035481565b61100581565b600281565b601081565b61100881565b603281565b600b81565b6004546005549091565b33612000146107215760405162461bcd60e51b815260040161050b906130cb565b60005460ff166107435760405162461bcd60e51b815260040161050b90612c9b565b61074b612670565b600061078c84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611c0d92505050565b9150915080156107d35781516040517f7f0956d47419b9525356e7111652b653b530ec6f5096dccc04589bc38e629967916107c6916132a4565b60405180910390a16106c9565b81516040517f7d45f62d17443dd4547bca8a8112c60e2385669318dc300ec61a5d2492f262e791610803916132a4565b60405180910390a15050505050565b600981565b662386f26fc1000081565b61100781565b61100681565b60005460ff1681565b600081565b600481565b60005460ff166108635760405162461bcd60e51b815260040161050b90612c9b565b33611007146108845760405162461bcd60e51b815260040161050b90612f88565b6108ef84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260148152731b5a5cd9195b59585b9bdc951a1c995cda1bdb1960621b60208201529150611c8d9050565b1561098a57602081146109145760405162461bcd60e51b815260040161050b90612e6b565b604080516020601f840181900481028201810190925282815260009161095291858580838501838280828437600092019190915250611ce792505050565b905060018110158015610966575060055481105b6109825760405162461bcd60e51b815260040161050b90613086565b600455610c9d565b6109f084848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600f81526e19995b1bdb9e551a1c995cda1bdb19608a1b60208201529150611c8d9050565b15610a8c5760208114610a155760405162461bcd60e51b815260040161050b90612fd6565b604080516020601f8401819004810282018101909252828152600091610a5391858580838501838280828437600092019190915250611ce792505050565b90506103e88111158015610a68575060045481115b610a845760405162461bcd60e51b815260040161050b90612d09565b600555610c9d565b610b0084848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601881527f66696e616c697479536c617368526577617264526174696f000000000000000060208201529150611c8d9050565b15610b9a5760208114610b255760405162461bcd60e51b815260040161050b906131c5565b604080516020601f8401819004810282018101909252828152600091610b6391858580838501838280828437600092019190915250611ce792505050565b9050600a8110158015610b765750606481105b610b925760405162461bcd60e51b815260040161050b90612e1f565b600655610c9d565b610c0e84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601881527f656e61626c654d616c6963696f7573566f7465536c617368000000000000000060208201529150611c8d9050565b15610c855760208114610c335760405162461bcd60e51b815260040161050b90612d3e565b604080516020601f8401819004810282018101909252828152610c6f9190848480838501838280828437600092019190915250611cec92505050565b6007805460ff1916911515919091179055610c9d565b60405162461bcd60e51b815260040161050b90613167565b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a84848484604051610cd29493929190612bcd565b60405180910390a150505050565b609681565b61100281565b3361200014610d0c5760405162461bcd60e51b815260040161050b906130cb565b60005460ff16610d2e5760405162461bcd60e51b815260040161050b90612c9b565b6040517f07db600eebe2ac176be8dcebad61858c245a4961bb32ca2aa3d159b09aa0810e90600090a1505050565b334114610d7b5760405162461bcd60e51b815260040161050b9061311a565b60005460ff16610d9d5760405162461bcd60e51b815260040161050b90612c9b565b6003544311610dbe5760405162461bcd60e51b815260040161050b90613210565b3a15610ddc5760405162461bcd60e51b815260040161050b90612f5a565b60405163155853f360e21b8152611000906355614fcc90610e01908490600401612b82565b60206040518083038186803b158015610e1957600080fd5b505afa158015610e2d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e51919061294c565b610e5a57611146565b610e6261264d565b506001600160a01b0381166000908152600260208181526040928390208351606081018552815481526001820154928101929092529091015460ff161580159282019290925290610ebd576020810180516001019052610f16565b60016040820181905260208201819052805480820182556000919091527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf60180546001600160a01b0319166001600160a01b0384161790555b438152600554602082015181610f2857fe5b0661107457600060208201526040516335409f7f60e01b8152611000906335409f7f90610f59908590600401612b82565b600060405180830381600087803b158015610f7357600080fd5b505af1158015610f87573d6000803e3d6000fd5b505050506120006001600160a01b031663f7a251d7600b610fa785611b3b565b60006040518463ffffffff1660e01b8152600401610fc7939291906132c3565b600060405180830381600087803b158015610fe157600080fd5b505af1925050508015610ff2575060015b61106f573d808015611020576040519150601f19603f3d011682016040523d82523d6000602084013e611025565b606091505b50826001600160a01b03167fd7bc86ff5d08c8ab043edec743302aba2520e6635172a428bc956721db9e2d1c83602001518360405161106592919061325d565b60405180910390a2505b6110e0565b60045481602001518161108357fe5b066110e0576040516375abf10160e11b81526110009063eb57e202906110ad908590600401612b82565b600060405180830381600087803b1580156110c757600080fd5b505af11580156110db573d6000803e3d6000fd5b505050505b6001600160a01b0382166000818152600260208181526040808420865181559186015160018301558581015191909201805460ff1916911515919091179055517fddb6012116e51abf5436d956a4f0ebd927e92c576ff96d7918290c8782291e3e9190a2505b5043600355565b60005460ff1661116f5760405162461bcd60e51b815260040161050b90612c9b565b604051630a83aaa960e31b81526110069063541d554890611194903390600401612b82565b60206040518083038186803b1580156111ac57600080fd5b505afa1580156111c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111e4919061294c565b6112005760405162461bcd60e51b815260040161050b90612bff565b60075460ff166112225760405162461bcd60e51b815260040161050b90612c66565b60065461122f5760146006555b8051514361010090910111801561125157504381602001516000015161010001115b61126d5760405162461bcd60e51b815260040161050b90612c36565b80602001516020015181600001516020015114801561129b5750806020015160600151816000015160600151145b156112b85760405162461bcd60e51b815260040161050b90612eb2565b8051604081015190511080156112d75750602081015160408101519051105b6112f35760405162461bcd60e51b815260040161050b90612de8565b6020810151518151511080156113185750806000015160400151816020015160400151105b8061134357508051516020820151511080156113435750806020015160400151816000015160400151105b8061135d5750806020015160400151816000015160400151145b6113795760405162461bcd60e51b815260040161050b90612cd2565b61138b81600001518260400151611d14565b80156113a457506113a481602001518260400151611d14565b6113c05760405162461bcd60e51b815260040161050b90612d89565b6060806110006001600160a01b0316633b071dcc6040518163ffffffff1660e01b815260040160006040518083038186803b1580156113fe57600080fd5b505afa158015611412573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261143a9190810190612889565b9150915060005b81518110156115775761146b82828151811061145957fe5b60200260200101518560400151611eec565b1561156f576006546040516309a99b4f60e41b815260646110028031909302049190639a99b4f0906114a39033908590600401612b96565b602060405180830381600087803b1580156114bd57600080fd5b505af11580156114d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114f59190612aa0565b506110006001600160a01b03166335409f7f85848151811061151357fe5b60200260200101516040518263ffffffff1660e01b81526004016115379190612b82565b600060405180830381600087803b15801561155157600080fd5b505af1158015611565573d6000803e3d6000fd5b5050505050611577565b600101611441565b50600061158984604001516000611f50565b90506120006001600160a01b031663f7a251d7600b6115ab8760400151611f6c565b60006040518463ffffffff1660e01b81526004016115cb939291906132c3565b600060405180830381600087803b1580156115e557600080fd5b505af19250505080156115f6575060015b611668573d808015611624576040519150601f19603f3d011682016040523d82523d6000602084013e611629565b606091505b50817fd58d1183100bd0932c0588f31c4205d6bc6168909765a96c41adbed3115f36288260405161165a9190612bba565b60405180910390a250611694565b60405181907f7b78aadacff901d8b63d0dba4f86283d4db8aef27f9ed70413dd860f1c9532b690600090a25b50505050565b601481565b61100381565b60005460ff16156116c85760405162461bcd60e51b815260040161050b90613018565b603260045560966005556000805460ff19166001179055565b61100081565b600381565b336110001461170d5760405162461bcd60e51b815260040161050b90612edf565b60005460ff1661172f5760405162461bcd60e51b815260040161050b90612c9b565b60015461173b57611b33565b600154600090600019015b808211611b07576000805b8284101561186a5761176161264d565b600260006001878154811061177257fe5b60009182526020808320909101546001600160a01b0316835282810193909352604091820190208151606081018352815481526001820154938101939093526002015460ff161515908201526005549091506004900481602001511115611854576004600554816117df57fe5b0481602001510381602001818152505080600260006001888154811061180157fe5b6000918252602080832091909101546001600160a01b0316835282810193909352604091820190208351815591830151600183015591909101516002909101805460ff191691151591909117905561185e565b600192505061186a565b50836001019350611751565b828411611a015761187961264d565b600260006001868154811061188a57fe5b60009182526020808320909101546001600160a01b0316835282810193909352604091820190208151606081018352815481526001820154938101939093526002015460ff161515908201526005549091506004900481602001511115611972576004600554816118f757fe5b0481602001510381602001818152505080600260006001878154811061191957fe5b6000918252602080832091909101546001600160a01b03168352828101939093526040918201902083518155918301516001808401919091559201516002909101805460ff19169115159190911790559150611a019050565b600260006001868154811061198357fe5b60009182526020808320909101546001600160a01b031683528201929092526040018120818155600181810192909255600201805460ff191690558054806119c757fe5b600082815260209020810160001990810180546001600160a01b0319169055019055836119f45750611a01565b506000199092019161186a565b818015611a0b5750805b15611aea576002600060018681548110611a2157fe5b60009182526020808320909101546001600160a01b031683528201929092526040018120818155600181810192909255600201805460ff19169055805484908110611a6857fe5b600091825260209091200154600180546001600160a01b039092169186908110611a8e57fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506001805480611ac757fe5b600082815260209020810160001990810180546001600160a01b03191690550190555b82611af6575050611b07565b505060019091019060001901611746565b6040517fcfdb3b6ccaeccbdc68be3c59c840e3b3c90f0a7c491f5fff1cf56cfda200dd9c90600090a150505b565b61100481565b60408051600480825260a08201909252606091829190816020015b6060815260200190600190039081611b56579050509050611b7f836001600160a01b0316611fa7565b81600081518110611b8c57fe5b6020026020010181905250611ba043611fca565b81600181518110611bad57fe5b6020908102919091010152611bc26038611fca565b81600281518110611bcf57fe5b6020026020010181905250611be342611fca565b81600381518110611bf057fe5b6020026020010181905250611c0481611fdd565b9150505b919050565b611c15612670565b6000611c1f612670565b611c27612682565b611c38611c3386612067565b61208c565b90506000805b611c47836120d6565b15611c805780611c7357611c62611c5d846120f7565b612145565b63ffffffff16845260019150611c78565b611c80565b600101611c3e565b5091935090915050915091565b600081604051602001611ca09190612b66565b6040516020818303038152906040528051906020012083604051602001611cc79190612b66565b604051602081830303815290604052805190602001201490505b92915050565b015190565b8082015160009060ff811615611d06576001915081611d0c565b60009150815b505092915050565b60408051600480825260a0820190925260009160609190816020015b6060815260200190600190039081611d30575050604080516020808252818301909252919250606091908082018180368337019050509050611d758560000151611fca565b82600081518110611d8257fe5b6020026020010181905250611d9d60208660200151836121c7565b611da6816121d7565b82600181518110611db357fe5b6020026020010181905250611dcb8560400151611fca565b82600281518110611dd857fe5b6020026020010181905250611df360208660600151836121c7565b611dfc816121d7565b82600381518110611e0957fe5b6020026020010181905250611e2f6020611e2284611fdd565b80519060200120836121c7565b6040805160b080825260e08201909252606091602082018180368337019050509050611e5f81836000602061222d565b611e718187608001516020606061222d565b611e7f81866080603061222d565b604080516001808252818301909252606091602082018180368337019050509050815160016020830182602086016066600019fa611ebc57600080fd5b506001611eca826000612280565b60ff1614611edf576000945050505050611ce1565b5060019695505050505050565b815181516000916001918114808314611f085760009250611f46565b600160208701838101602088015b600284838510011415611f41578051835114611f355760009650600093505b60209283019201611f16565b505050505b5090949350505050565b60008160200183511015611f6357600080fd5b50016020015190565b60408051600480825260a08201909252606091829190816020015b6060815260200190600190039081611f87579050509050611b7f836121d7565b60408051600560a21b8318601482015260348101909152606090611c04816121d7565b6060611ce1611fd88361229c565b6121d7565b6060815160001415611ffe5750604080516000815260208101909152611c08565b60608260008151811061200d57fe5b602002602001015190506000600190505b835181101561204e576120448285838151811061203757fe5b6020026020010151612382565b915060010161201e565b50611c04612061825160c060ff166123ff565b82612382565b61206f6126a2565b506040805180820190915281518152602082810190820152919050565b612094612682565b61209d826124d1565b6120a657600080fd5b60006120b5836020015161250b565b60208085015160408051808201909152868152920190820152915050919050565b60006120e06126a2565b505080518051602091820151919092015191011190565b6120ff6126a2565b612108826120d6565b61211157600080fd5b602082015160006121218261256e565b80830160209586015260408051808201909152908152938401919091525090919050565b80516000901580159061215a57508151602110155b61216357600080fd5b6000612172836020015161250b565b905080836000015110156121985760405162461bcd60e51b815260040161050b9061304f565b8251602080850151830180519284900392918310156121be57826020036101000a820491505b50949350505050565b9091018181526020918201910152565b6060815160011480156122095750607f60f81b826000815181106121f757fe5b01602001516001600160f81b03191611155b15612215575080611c08565b611ce16122278351608060ff166123ff565b83612382565b60005b818110156106c95783818151811061224457fe5b602001015160f81c60f81b85848060010195508151811061226157fe5b60200101906001600160f81b031916908160001a905350600101612230565b6000816001018351101561229357600080fd5b50016001015190565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff1984166122e057506018612304565b6fffffffffffffffffffffffffffffffff19841661230057506010612304565b5060005b602081101561233a5781818151811061231957fe5b01602001516001600160f81b031916156123325761233a565b600101612304565b60008160200390506060816040519080825280601f01601f19166020018201604052801561236f576020820181803683370190505b5080830196909652508452509192915050565b6060806040519050835180825260208201818101602087015b818310156123b357805183526020928301920161239b565b50855184518101855292509050808201602086015b818310156123e05780518352602092830192016123c8565b508651929092011591909101601f01601f191660405250905092915050565b60606801000000000000000083106124295760405162461bcd60e51b815260040161050b90612dc0565b604080516001808252818301909252606091602082018180368337019050509050603784116124835782840160f81b8160008151811061246557fe5b60200101906001600160f81b031916908160001a9053509050611ce1565b606061248e8561229c565b90508381510160370160f81b826000815181106124a757fe5b60200101906001600160f81b031916908160001a9053506124c88282612382565b95945050505050565b80516000906124e257506000611c08565b6020820151805160001a9060c082101561250157600092505050611c08565b5060019392505050565b8051600090811a6080811015612525576000915050611c08565b60b8811080612540575060c08110801590612540575060f881105b1561254f576001915050611c08565b60c08110156125635760b519019050611c08565b60f519019050611c08565b80516000908190811a60808110156125895760019150612646565b60b881101561259e57607e1981019150612646565b60c08110156125ef57600060b78203600186019550806020036101000a8651049150600181018201935050808310156125e95760405162461bcd60e51b815260040161050b90612f2f565b50612646565b60f88110156126045760be1981019150612646565b600060f78203600186019550806020036101000a865104915060018101820193505080831015611d0c5760405162461bcd60e51b815260040161050b90612f2f565b5092915050565b604051806060016040528060008152602001600081526020016000151581525090565b60408051602081019091526000815290565b60405180604001604052806126956126a2565b8152602001600081525090565b604051806040016040528060008152602001600081525090565b600082601f8301126126cc578081fd5b81516126df6126da82613316565b6132ef565b818152915060208083019084810160005b84811015612755578151870188603f82011261270b57600080fd5b8381015161271b6126da82613336565b81815260408b8184860101111561273157600080fd5b6127408388840183870161335a565b508652505092820192908201906001016126f0565b505050505092915050565b60008083601f840112612771578182fd5b50813567ffffffffffffffff811115612788578182fd5b6020830191508360208285010111156127a057600080fd5b9250929050565b600082601f8301126127b7578081fd5b81356127c56126da82613336565b91508082528360208285010111156127dc57600080fd5b8060208401602084013760009082016020015292915050565b600060a08284031215612806578081fd5b61281060a06132ef565b905081358152602082013560208201526040820135604082015260608201356060820152608082013567ffffffffffffffff81111561284e57600080fd5b61285a848285016127a7565b60808301525092915050565b600060208284031215612877578081fd5b813561288281613386565b9392505050565b6000806040838503121561289b578081fd5b825167ffffffffffffffff808211156128b2578283fd5b81850186601f8201126128c3578384fd5b805192506128d36126da84613316565b80848252602080830192508084018a8283890287010111156128f3578788fd5b8794505b8685101561291e57805161290a81613386565b8452600194909401939281019281016128f7565b508801519096509350505080821115612935578283fd5b50612942858286016126bc565b9150509250929050565b60006020828403121561295d578081fd5b81518015158114612882578182fd5b60008060008060408587031215612981578182fd5b843567ffffffffffffffff80821115612998578384fd5b6129a488838901612760565b909650945060208701359150808211156129bc578384fd5b506129c987828801612760565b95989497509550505050565b6000602082840312156129e6578081fd5b813567ffffffffffffffff808211156129fd578283fd5b81840160608187031215612a0f578384fd5b612a1960606132ef565b9250803582811115612a29578485fd5b612a35878284016127f5565b845250602081013582811115612a49578485fd5b612a55878284016127f5565b602085015250604081013582811115612a6c578485fd5b612a78878284016127a7565b6040850152509195945050505050565b600060208284031215612a99578081fd5b5035919050565b600060208284031215612ab1578081fd5b5051919050565b600080600060408486031215612acc578283fd5b833560ff81168114612adc578384fd5b9250602084013567ffffffffffffffff811115612af7578283fd5b612b0386828701612760565b9497909650939450505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b60008151808452612b5281602086016020860161335a565b601f01601f19169290920160200192915050565b60008251612b7881846020870161335a565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b03929092168252602082015260400190565b901515815260200190565b6000602082526128826020830184612b3a565b600060408252612be1604083018688612b10565b8281036020840152612bf4818587612b10565b979650505050505050565b6020808252601f908201527f746865206d73672073656e646572206973206e6f7420612072656c6179657200604082015260600190565b6020808252601690820152751d1bdbc81bdb1908189b1bd8dac81a5b9d9bdb1d995960521b604082015260600190565b6020808252818101527f6d616c6963696f757320766f746520736c617368206e6f7420656e61626c6564604082015260600190565b60208082526019908201527f74686520636f6e7472616374206e6f7420696e69742079657400000000000000604082015260600190565b6020808252601a908201527f6e6f2076696f6c6174696f6e206f6620766f74652072756c6573000000000000604082015260600190565b6020808252818101527f7468652066656c6f6e795468726573686f6c64206f7574206f662072616e6765604082015260600190565b6020808252602b908201527f6c656e677468206f6620656e61626c654d616c6963696f7573566f7465536c6160408201526a0e6d040dad2e6dac2e8c6d60ab1b606082015260800190565b60208082526017908201527f766572696679207369676e6174757265206661696c6564000000000000000000604082015260600190565b6020808252600e908201526d696e70757420746f6f206c6f6e6760901b604082015260600190565b60208082526019908201527f7372634e756d20626967676572207468616e207461724e756d00000000000000604082015260600190565b6020808252602c908201527f7468652066696e616c69747920736c6173682072657761726420726174696f2060408201526b6f7574206f662072616e676560a01b606082015260800190565b60208082526027908201527f6c656e677468206f66206d697364656d65616e6f725468726573686f6c64206d6040820152660d2e6dac2e8c6d60cb1b606082015260800190565b60208082526013908201527274776f206964656e746963616c20766f74657360681b604082015260600190565b60208082526030908201527f746865206d6573736167652073656e646572206d7573742062652076616c696460408201526f185d1bdc94d95d0818dbdb9d1c9858dd60821b606082015260800190565b6020808252601190820152706164646974696f6e206f766572666c6f7760781b604082015260600190565b6020808252601490820152736761737072696365206973206e6f74207a65726f60601b604082015260600190565b6020808252602e908201527f746865206d6573736167652073656e646572206d75737420626520676f76657260408201526d1b985b98d94818dbdb9d1c9858dd60921b606082015260800190565b60208082526022908201527f6c656e677468206f662066656c6f6e795468726573686f6c64206d69736d61746040820152610c6d60f31b606082015260800190565b60208082526019908201527f74686520636f6e747261637420616c726561647920696e697400000000000000604082015260600190565b6020808252601a908201527f6c656e677468206973206c657373207468616e206f6666736574000000000000604082015260600190565b60208082526025908201527f746865206d697364656d65616e6f725468726573686f6c64206f7574206f662060408201526472616e676560d81b606082015260800190565b6020808252602f908201527f746865206d6573736167652073656e646572206d7573742062652063726f737360408201526e0818da185a5b8818dbdb9d1c9858dd608a1b606082015260800190565b6020808252602d908201527f746865206d6573736167652073656e646572206d75737420626520746865206260408201526c3637b1b590383937b23ab1b2b960991b606082015260800190565b6020808252600d908201526c756e6b6e6f776e20706172616d60981b604082015260600190565b6020808252601e908201527f7265636569766520756e65787065637465642073796e207061636b6167650000604082015260600190565b6020808252602b908201527f6c656e677468206f662066696e616c697479536c61736852657761726452617460408201526a0d2de40dad2e6dac2e8c6d60ab1b606082015260800190565b6020808252818101527f63616e206e6f7420736c61736820747769636520696e206f6e6520626c6f636b604082015260600190565b61ffff91909116815260200190565b90815260200190565b6000838252604060208301526132766040830184612b3a565b949350505050565b918252602082015260400190565b92835260208301919091521515604082015260600190565b63ffffffff91909116815260200190565b60ff91909116815260200190565b600060ff85168252606060208301526132df6060830185612b3a565b9050826040830152949350505050565b60405181810167ffffffffffffffff8111828210171561330e57600080fd5b604052919050565b600067ffffffffffffffff82111561332c578081fd5b5060209081020190565b600067ffffffffffffffff82111561334c578081fd5b50601f01601f191660200190565b60005b8381101561337557818101518382015260200161335d565b838111156116945750506000910152565b6001600160a01b038116811461339b57600080fd5b5056fea26469706673582212207e6be46f5e0281709e9788d33be4928c51610752d8a32e78d1c8c64bea3df55764736f6c63430006040033", + }, + { + ContractAddr: common.HexToAddress(SystemRewardContract), + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/b144718e94d7a1ebb24a7103202300f08826f369", + Code: "6080604052600436106101a05760003560e01c80637942fd05116100ec578063ac4317511161008a578063f9a2bbc711610064578063f9a2bbc714610550578063fb5478b314610565578063fc3e59081461057a578063fd6a68791461058f576101e4565b8063ac43175114610457578063c81b166214610526578063dc927faf1461053b576101e4565b80639dc09262116100c65780639dc0926214610403578063a1a11bf514610418578063a78abc161461042d578063ab51bb9614610442576101e4565b80637942fd05146103a057806396713da9146103b55780639a99b4f0146103ca576101e4565b80634bf6c882116101595780636e47b482116101335780636e47b4821461034c57806370fd5bad14610361578063718a8aa81461037657806375d47a0a1461038b576101e4565b80634bf6c882146102db57806351e80672146102f05780636d70f7ae14610305576101e4565b80630bee7a67146101e95780630e2374a5146102175780633a0b0eff146102485780633dffc3871461026f57806343756e5c1461029a578063493279b1146102af576101e4565b366101e45734156101e25760408051348152905133917f6c98249d85d88c3753a04a22230f595e4dc8d3dc86c34af35deeeedc861b89db919081900360200190a25b005b600080fd5b3480156101f557600080fd5b506101fe6105a4565b6040805163ffffffff9092168252519081900360200190f35b34801561022357600080fd5b5061022c6105a9565b604080516001600160a01b039092168252519081900360200190f35b34801561025457600080fd5b5061025d6105af565b60408051918252519081900360200190f35b34801561027b57600080fd5b506102846105b5565b6040805160ff9092168252519081900360200190f35b3480156102a657600080fd5b5061022c6105ba565b3480156102bb57600080fd5b506102c46105c0565b6040805161ffff9092168252519081900360200190f35b3480156102e757600080fd5b506102846105c5565b3480156102fc57600080fd5b5061022c6105ca565b34801561031157600080fd5b506103386004803603602081101561032857600080fd5b50356001600160a01b03166105d0565b604080519115158252519081900360200190f35b34801561035857600080fd5b5061022c6105ee565b34801561036d57600080fd5b506102846105f4565b34801561038257600080fd5b506102846105f9565b34801561039757600080fd5b5061022c6105fe565b3480156103ac57600080fd5b50610284610604565b3480156103c157600080fd5b50610284610609565b3480156103d657600080fd5b5061025d600480360360408110156103ed57600080fd5b506001600160a01b03813516906020013561060e565b34801561040f57600080fd5b5061022c6107b9565b34801561042457600080fd5b5061022c6107bf565b34801561043957600080fd5b506103386107c5565b34801561044e57600080fd5b506101fe6107ce565b34801561046357600080fd5b506101e26004803603604081101561047a57600080fd5b81019060208101813564010000000081111561049557600080fd5b8201836020820111156104a757600080fd5b803590602001918460018302840111640100000000831117156104c957600080fd5b9193909290916020810190356401000000008111156104e757600080fd5b8201836020820111156104f957600080fd5b8035906020019184600183028401116401000000008311171561051b57600080fd5b5090925090506107d3565b34801561053257600080fd5b5061022c610b56565b34801561054757600080fd5b5061022c610b5c565b34801561055c57600080fd5b5061022c610b62565b34801561057157600080fd5b5061025d610b68565b34801561058657600080fd5b50610284610b74565b34801561059b57600080fd5b5061022c610b79565b606481565b61200181565b60015481565b600181565b61100181565b603881565b600881565b61200081565b6001600160a01b031660009081526002602052604090205460ff1690565b61100581565b600281565b601081565b61100881565b600b81565b600981565b6000805460ff1661068b57600260208190527fe57bda0a954a7c7381b17b2c763e646ba2c60f67292d287ba583603e2c1c41668054600160ff19918216811790925561100560009081527fe25235fc0de9d7165652bef0846fefda506174abb9a190f03d0f7bcc6146dbce80548316841790559282558254161790555b3360009081526002602052604090205460ff166106d95760405162461bcd60e51b815260040180806020018281038252602b815260200180610c67602b913960400191505060405180910390fd5b60004783106106e857476106ea565b825b9050670de0b6b3a76400008111156107075750670de0b6b3a76400005b8015610788576040516001600160a01b0385169082156108fc029083906000818181858888f19350505050158015610743573d6000803e3d6000fd5b506040805182815290516001600160a01b038616917ff8b71c64315fc33b2ead2adfa487955065152a8ac33d9d5193aafd7f45dc15a0919081900360200190a26107b2565b6040517fe589651933c2457488cc0d8e0941518abf748e799435e4e396d9c4d0b2db2d4d90600090a15b9392505050565b61100781565b61100681565b60005460ff1681565b600081565b33611007146108135760405162461bcd60e51b815260040180806020018281038252602e815260200180610cc1602e913960400191505060405180910390fd5b61087584848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600b81526a30b23227b832b930ba37b960a91b60208201529150610b7f9050565b1561094d57606082828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050825192935050601490911490506108f85760405162461bcd60e51b815260040180806020018281038252602c815260200180610cef602c913960400191505060405180910390fd5b60148101516001600160a01b038116600081815260026020526040808220805460ff19166001179055517f9870d7fe5d112134c55844951dedf365363006d9c588db07c4c85af6322a06199190a25050610ac4565b6109b284848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600e81526d3232b632ba32a7b832b930ba37b960911b60208201529150610b7f9050565b15610a8757606082828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505082519293505060149091149050610a355760405162461bcd60e51b815260040180806020018281038252602f815260200180610c92602f913960400191505060405180910390fd5b60148101516001600160a01b038116600081815260026020526040808220805460ff19169055517fb40992a19dba61ea600e87fce607102bf5908dc89076217b6ca6ae195224f7029190a25050610ac4565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b61100281565b61100381565b61100081565b670de0b6b3a764000081565b600381565b61100481565b6000816040516020018082805190602001908083835b60208310610bb45780518252601f199092019160209182019101610b95565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b60208310610c225780518252601f199092019160209182019101610c03565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051602081830303815290604052805190602001201490509291505056fe6f6e6c79206f70657261746f7220697320616c6c6f77656420746f2063616c6c20746865206d6574686f646c656e677468206f662076616c756520666f722064656c6574654f70657261746f722073686f756c64206265203230746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e74726163746c656e677468206f662076616c756520666f72206164644f70657261746f722073686f756c64206265203230a264697066735822122078be72e2672a87e28d3e6849bea141a139b304a089fceb003c016dabd5f556fb64736f6c63430006040033", + }, + { + ContractAddr: common.HexToAddress(RelayerHubContract), + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/b144718e94d7a1ebb24a7103202300f08826f369", + Code: "608060405234801561001057600080fd5b50600436106102275760003560e01c80638f83ab1311610130578063c81b1662116100b8578063f3ae24151161007c578063f3ae2415146104e8578063f9a2bbc71461050e578063fc3e590814610516578063fd30d9b81461051e578063fd6a68791461052657610227565b8063c81b1662146104c0578063dc927faf146104c8578063dd91d1c5146104d0578063e1c7392a146104d8578063e79a198f146104e057610227565b8063a1a11bf5116100ff578063a1a11bf5146103de578063a74b83ca146103e6578063a78abc16146103ee578063ab51bb96146103f6578063ac431751146103fe57610227565b80638f83ab13146103a057806395468d26146103c657806396713da9146103ce5780639dc09262146103d657610227565b8063541d5548116101b3578063718a8aa811610182578063718a8aa81461034857806375d47a0a1461035057806378beee67146103585780637942fd051461037e5780637ae230881461038657610227565b8063541d5548146102d85780636a6a419e146103125780636e47b4821461033857806370fd5bad1461034057610227565b80633dffc387116101fa5780633dffc3871461028357806343756e5c146102a1578063493279b1146102a95780634bf6c882146102c857806351e80672146102d057610227565b806303aff02b1461022c578063049a5716146102365780630bee7a671461025a5780630e2374a51461027b575b600080fd5b61023461052e565b005b61023e610539565b604080516001600160a01b039092168252519081900360200190f35b610262610551565b6040805163ffffffff9092168252519081900360200190f35b61023e610556565b61028b61055c565b6040805160ff9092168252519081900360200190f35b61023e610561565b6102b1610567565b6040805161ffff9092168252519081900360200190f35b61028b61056c565b61023e610571565b6102fe600480360360208110156102ee57600080fd5b50356001600160a01b0316610577565b604080519115158252519081900360200190f35b6102fe6004803603602081101561032857600080fd5b50356001600160a01b0316610595565b61023e6105b3565b61028b6105b9565b61028b6105be565b61023e6105c3565b6102346004803603602081101561036e57600080fd5b50356001600160a01b03166105c9565b61028b6107b1565b61038e6107b6565b60408051918252519081900360200190f35b610234600480360360208110156103b657600080fd5b50356001600160a01b03166107c3565b61038e610a02565b61028b610a0e565b61023e610a13565b61023e610a19565b61023e610a1f565b6102fe610a37565b610262610a40565b6102346004803603604081101561041457600080fd5b81019060208101813564010000000081111561042f57600080fd5b82018360208201111561044157600080fd5b8035906020019184600183028401116401000000008311171561046357600080fd5b91939092909160208101903564010000000081111561048157600080fd5b82018360208201111561049357600080fd5b803590602001918460018302840111640100000000831117156104b557600080fd5b509092509050610a45565b61023e610d96565b61023e610d9c565b610234610da2565b610234610e43565b610234610ec5565b6102fe600480360360208110156104fe57600080fd5b50356001600160a01b031661107e565b61023e61109c565b61028b6110a2565b6102fe6110a7565b61023e6110b0565b610537336110b6565b565b73b005741528b86f5952469d80a8614591e3c5b63281565b606481565b61200181565b600181565b61100181565b603881565b600881565b61200081565b6001600160a01b031660009081526007602052604090205460ff1690565b6001600160a01b031660009081526008602052604090205460ff1690565b61100581565b600281565b601081565b61100881565b3360009081526008602052604090205460ff166106175760405162461bcd60e51b81526004018080602001828103825260248152602001806115c26024913960400191505060405180910390fd5b61062033611218565b1561065c5760405162461bcd60e51b815260040180806020018281038252602181526020018061157f6021913960400191505060405180910390fd5b3233146106b0576040805162461bcd60e51b815260206004820152601e60248201527f70726f766973696f6e616c2072656c6179657220697320612070726f78790000604482015290519081900360640190fd5b6001600160a01b038181166000908152600960205260409020541633146107085760405162461bcd60e51b815260040180806020018281038252602781526020018061163b6027913960400191505060405180910390fd5b6001600160a01b03818116600081815260066020908152604080832080543380865260078086528487208054600160ff199182161790915584546001600160a01b031990811684179095556008875285882080548216905597875260098652848720805490941690935596168085529083529281902080549094169093558251828152908101939093528151909260008051602061166283398151915292908290030190a15050565b600b81565b68056bc75e2d6310000081565b3360009081526005602052604090205460ff16610820576040805162461bcd60e51b81526020600482015260166024820152751b585b9859d95c88191bd95cc81b9bdd08195e1a5cdd60521b604482015290519081900360640190fd5b61082981611218565b156108655760405162461bcd60e51b81526004018080602001828103825260278152602001806115e66027913960400191505060405180910390fd5b6001600160a01b03811615610921576001600160a01b03811660009081526007602052604090205460ff16156108db576040805162461bcd60e51b815260206004820152601660248201527572656c6179657220616c72656164792065786973747360501b604482015290519081900360640190fd5b6001600160a01b0381166000818152600860209081526040808320805460ff191660011790553383526009909152902080546001600160a01b03191690911790556109c2565b3360008181526006602090815260408083208054600980855283862080546001600160a01b03198085169095556001600160a01b0393841680895260078852868920805460ff19908116909155918516808a5260088952878a20805490931690925598909752908552805490921690915581518581529086169281019290925280516000805160206116628339815191529281900390910190a150506109ff565b604080516001600160a01b038316815290517ffba56633276570c7d3120d4535bf3bce26523da53958e40734210b9fd99b36939181900360200190a15b50565b67016345785d8a000081565b600981565b61100781565b61100681565b73446aa6e0dc65690403df3f127750da1322941f3e81565b60005460ff1681565b600081565b60005460ff16610a98576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b3361100714610ad85760405162461bcd60e51b815260040180806020018281038252602e81526020018061160d602e913960400191505060405180910390fd5b610b3984848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600a81526930b23226b0b730b3b2b960b11b6020820152915061121e9050565b15610bd15760148114610b7d5760405162461bcd60e51b81526004018080602001828103825260228152602001806115a06022913960400191505060405180910390fd5b6000610bc0601484848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061130592505050565b9050610bcb8161130a565b50610d04565b610c3584848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600d81526c3932b6b7bb32a6b0b730b3b2b960991b6020820152915061121e9050565b15610cc75760148114610c795760405162461bcd60e51b81526004018080602001828103825260228152602001806115a06022913960400191505060405180910390fd5b6000610cbc601484848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061130592505050565b9050610bcb816110b6565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b61100281565b61100381565b600a5460ff1615610dfa576040805162461bcd60e51b815260206004820152601e60248201527f7468652077686974656c6973747320616c726561647920757064617465640000604482015290519081900360640190fd5b610e1773b005741528b86f5952469d80a8614591e3c5b6326113cc565b610e3473446aa6e0dc65690403df3f127750da1322941f3e6113cc565b600a805460ff19166001179055565b60005460ff1615610e9b576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b68056bc75e2d63100000600190815567016345785d8a00006002556000805460ff19169091179055565b3360009081526004602052604090205460ff16610f20576040805162461bcd60e51b81526020600482015260146024820152731c995b185e595c88191bc81b9bdd08195e1a5cdd60621b604482015290519081900360640190fd5b60005460ff16610f73576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b610f7b611564565b5033600081815260036020908152604091829020825180840190935280548084526001909101549183018290529192916108fc91610fbf919063ffffffff61148416565b6040518115909202916000818181858888f19350505050158015610fe7573d6000803e3d6000fd5b50602081015160405161100291829181156108fc0291906000818181858888f1935050505015801561101d573d6000803e3d6000fd5b50336000818152600460209081526040808320805460ff191690556003825280832083815560010192909255815192835290517fd17202129b83db7880d6b9f25df81c58ad46f7e0e2c92236b1aa10663a4876679281900390910190a15050565b6001600160a01b031660009081526005602052604090205460ff1690565b61100081565b600381565b600a5460ff1681565b61100481565b6001600160a01b03811660009081526005602052604090205460ff1661111b576040805162461bcd60e51b81526020600482015260156024820152741b585b9859d95c88191bd95cdb89dd08195e1a5cdd605a1b604482015290519081900360640190fd5b6001600160a01b038082166000818152600660209081526040808320805460058452828520805460ff1990811690915582546001600160a01b0319908116909355600980865284872080548a16885260088752858820805490931690925595879052948452845490911690935580519384525191909316927f2002866d443ac6c241fecaaa2af4895828c7de2cc423b9d01f7969650f557c76928290030190a16001600160a01b03811615611214576001600160a01b0381166000818152600760209081526040808320805460ff1916905580519384529083019190915280516000805160206116628339815191529281900390910190a15b5050565b3b151590565b6000816040516020018082805190602001908083835b602083106112535780518252601f199092019160209182019101611234565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b602083106112c15780518252601f1990920191602091820191016112a2565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b015190565b6001600160a01b03811660009081526005602052604090205460ff1615611371576040805162461bcd60e51b81526020600482015260166024820152756d616e6167657220616c72656164792065786973747360501b604482015290519081900360640190fd5b6001600160a01b038116600081815260056020908152604091829020805460ff19166001179055815192835290517fe0de8e71a22c046647f4ef744348fa126ad6d052d4ce070999481f69d45575179281900390910190a150565b6001600160a01b03811660008181526005602090815260408083208054600160ff1991821681179092556006845282852080546001600160a01b031916871790556007845293829020805490941617909255815192835290517fe0de8e71a22c046647f4ef744348fa126ad6d052d4ce070999481f69d45575179281900390910190a160408051600081526001600160a01b03831660208201528151600080516020611662833981519152929181900390910190a150565b60006114c683836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506114cd565b9392505050565b6000818484111561155c5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015611521578181015183820152602001611509565b50505050905090810190601f16801561154e5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b60405180604001604052806000815260200160008152509056fe70726f766973696f6e616c2072656c61796572206973206120636f6e74726163746c656e677468206f66206d616e616765722061646472657373206d69736d6174636872656c61796572206973206e6f7420612070726f766973696f6e616c2072656c61796572636f6e7472616374206973206e6f7420616c6c6f77656420746f20626520612072656c61796572746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e747261637470726f766973696f6e616c206973206e6f742073657420666f722074686973206d616e61676572a5a19d7e9dab30a215022382d7abe782b579986fcbedec9942ecd0db9510a148a2646970667358221220ca640b19c40787a49d8b8b52c563d76e0125386bfdf94825087004f989e9989d64736f6c63430006040033", + }, + { + ContractAddr: common.HexToAddress(CrossChainContract), + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/b144718e94d7a1ebb24a7103202300f08826f369", + Code: "608060405234801561001057600080fd5b50600436106103995760003560e01c8063718a8aa8116101e9578063c27cdcfb1161010f578063dc927faf116100ad578063f7a251d71161007c578063f7a251d714610b2f578063f9a2bbc714610ba7578063fc3e590814610baf578063fd6a687914610bb757610399565b8063dc927faf14610af7578063e1c7392a14610aff578063e3b0480514610b07578063e6400bbe14610b2757610399565b8063ccc108d7116100e9578063ccc108d714610ab0578063d31f968d14610ab8578063d76a867514610ae7578063dc40433114610aef57610399565b8063c27cdcfb14610a80578063c780e9de14610aa0578063c81b166214610aa857610399565b80638cc8f56111610187578063a78abc1611610156578063a78abc16146109b2578063ab51bb96146109ba578063ac431751146109c2578063b0355f5b1461078157610399565b80638cc8f5611461088757806396713da91461099a5780639dc09262146109a2578063a1a11bf5146109aa57610399565b806375d47a0a116101c357806375d47a0a146108a75780637942fd05146108af57806384013b6a146108b7578063863fe4ab1461099257610399565b8063718a8aa81461088f578063719482d51461089757806374f079b81461089f57610399565b8063422f9050116102ce57806363e1394e1161026c5780636de380bd1161023b5780636de380bd146108575780636e47a51a1461085f5780636e47b4821461087f57806370fd5bad1461088757610399565b806363e1394e146107ff5780636a3cb34d146108075780636bacff2c1461080f5780636c46aa681461080757610399565b80634bf6c882116102a85780634bf6c882146107b957806351e80672146107c15780635692ddd3146107c95780635f832177146107d157610399565b8063422f90501461078957806343756e5c146107a9578063493279b1146107b157610399565b8063299b533d1161033b578063308325f411610315578063308325f4146106155780633a648b151461061d5780633bdc47a6146106595780633dffc3871461078157610399565b8063299b533d146105a35780632af6f399146105d75780632ff32aea146105f457610399565b806314b3023b1161037757806314b3023b146104015780631d1309351461041b5780631e275ae11461043757806322556cdc1461059b57610399565b806305e682581461039e5780630bee7a67146103bc5780630e2374a5146103dd575b600080fd5b6103a6610bbf565b6040805160ff9092168252519081900360200190f35b6103c4610bc4565b6040805163ffffffff9092168252519081900360200190f35b6103e5610bc9565b604080516001600160a01b039092168252519081900360200190f35b610409610bcf565b60408051918252519081900360200190f35b610423610bd5565b604080519115158252519081900360200190f35b610599600480360361010081101561044e57600080fd5b81018160a081016080820135600160201b81111561046b57600080fd5b82018360208201111561047d57600080fd5b803590602001918460018302840111600160201b8311171561049e57600080fd5b919390929091602081019035600160201b8111156104bb57600080fd5b8201836020820111156104cd57600080fd5b803590602001918460018302840111600160201b831117156104ee57600080fd5b919390929091602081019035600160201b81111561050b57600080fd5b82018360208201111561051d57600080fd5b803590602001918460018302840111600160201b8311171561053e57600080fd5b919390929091602081019035600160201b81111561055b57600080fd5b82018360208201111561056d57600080fd5b803590602001918460018302840111600160201b8311171561058e57600080fd5b509092509050610bde565b005b6104096112c2565b6105c0600480360360208110156105b957600080fd5b50356112c7565b6040805161ffff9092168252519081900360200190f35b610423600480360360208110156105ed57600080fd5b50356112dd565b6105fc6112f2565b60408051600792830b90920b8252519081900360200190f35b6104096112fb565b61063d6004803603602081101561063357600080fd5b503560ff16611301565b604080516001600160401b039092168252519081900360200190f35b61070c6004803603606081101561066f57600080fd5b60ff82351691602081013591810190606081016040820135600160201b81111561069857600080fd5b8201836020820111156106aa57600080fd5b803590602001918460018302840111600160201b831117156106cb57600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061131c945050505050565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561074657818101518382015260200161072e565b50505050905090810190601f1680156107735780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6103a6611392565b6104236004803603602081101561079f57600080fd5b503560ff16611397565b6103e56113ac565b6105c06113b2565b6103a66113b7565b6103e56113bc565b6104096113c2565b610599600480360360408110156107e757600080fd5b506001600160a01b03813581169160200135166113f2565b610409611652565b6105c061167a565b61082c6004803603602081101561082557600080fd5b503561167f565b6040805161ffff90941684526001600160801b03909216602084015282820152519081900360600190f35b6104096116ae565b6103e56004803603602081101561087557600080fd5b503560ff166116d5565b6103e56116f0565b6103a661167a565b6103a66116f6565b6105c0611392565b6104096116fb565b6103e5611701565b6103a6611707565b610599600480360360a08110156108cd57600080fd5b810190602081018135600160201b8111156108e757600080fd5b8201836020820111156108f957600080fd5b803590602001918460018302840111600160201b8311171561091a57600080fd5b919390929091602081019035600160201b81111561093757600080fd5b82018360208201111561094957600080fd5b803590602001918460018302840111600160201b8311171561096a57600080fd5b919350915080356001600160401b03908116916020810135909116906040013560ff1661170c565b6104096129c6565b6103a66129ce565b6103e56129d3565b6103e56129d9565b6104236129df565b6103c4610bbf565b610599600480360360408110156109d857600080fd5b810190602081018135600160201b8111156109f257600080fd5b820183602082011115610a0457600080fd5b803590602001918460018302840111600160201b83111715610a2557600080fd5b919390929091602081019035600160201b811115610a4257600080fd5b820183602082011115610a5457600080fd5b803590602001918460018302840111600160201b83111715610a7557600080fd5b5090925090506129e8565b61063d60048036036020811015610a9657600080fd5b503560ff166134ac565b6104096134c7565b6103e56134eb565b6105996134f1565b61042360048036036040811015610ace57600080fd5b5080356001600160a01b0316906020013560ff16613745565b61070c613765565b610409613784565b6103e561378a565b610599613790565b61063d60048036036020811015610b1d57600080fd5b503560ff16613b47565b610599613b62565b61059960048036036060811015610b4557600080fd5b60ff8235169190810190604081016020820135600160201b811115610b6957600080fd5b820183602082011115610b7b57600080fd5b803590602001918460018302840111600160201b83111715610b9c57600080fd5b919350915035613d81565b6103e5613ec4565b6103a6613eca565b6103e5613ecf565b600081565b606481565b61200181565b60015481565b600b5460ff1681565b60005460ff16610c23576040805162461bcd60e51b815260206004820152601960248201526000805160206149b2833981519152604482015290519081900360640190fd5b604080516337d7f9c160e21b81526001600160401b038b35166004820181905291516110039163df5fe704916024808301926020929190829003018186803b158015610c6e57600080fd5b505afa158015610c82573d6000803e3d6000fd5b505050506040513d6020811015610c9857600080fd5b5051610cd55760405162461bcd60e51b81526004018080602001828103825260238152602001806149d26023913960400191505060405180910390fd5b604080516337d7f9c160e21b815260208c8101356001600160401b03166004830181905292516110039263df5fe704926024808301939192829003018186803b158015610d2157600080fd5b505afa158015610d35573d6000803e3d6000fd5b505050506040513d6020811015610d4b57600080fd5b5051610d885760405162461bcd60e51b81526004018080602001828103825260238152602001806149d26023913960400191505060405180910390fd5b60608b013560ff81166000908152600560205260409020546001600160401b03909116906001600160a01b0316610e01576040805162461bcd60e51b815260206004820152601860248201527718da185b9b995b081a5cc81b9bdd081cdd5c1c1bdc9d195960421b604482015290519081900360640190fd5b600b5460ff1615610e45576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b8888604051808383808284376040519201829003822094508f93508e9250819050838380828437808301925050509250505060405180910390201415610ec1576040805162461bcd60e51b815260206004820152600c60248201526b1cd85b59481c185e5b1bd85960a21b604482015290519081900360640190fd5b60606001600160401b0360408e01358116908e83013516610ee28282613ed5565b80516020808301919091206000818152600e9092526040909120549194509060ff1615610f4b576040805162461bcd60e51b8152602060048201526012602482015271185b1c9958591e4818da185b1b195b99d95960721b604482015290519081900360640190fd5b6000908152600e60205260408120805460ff191660011790558f8160200201356001600160401b0316905060608f8f8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050905060608c8c8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052506040805163cba510a960e01b81526001600160401b038a16600482015290519596509094611003945063cba510a9935060248083019350602092829003018186803b15801561104157600080fd5b505afa158015611055573d6000803e3d6000fd5b505050506040513d602081101561106b57600080fd5b505160408051808201909152600381526269626360e81b6020820152909150611098908290898686613f1d565b6110e1576040805162461bcd60e51b81526020600482015260156024820152740696e76616c6964206d65726b6c652070726f6f663605c1b604482015290519081900360640190fd5b5050505060008f6001600481106110f457fe5b60200201356001600160401b0316905060608d8d8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8f018190048102820181019092528d815293945060609392508d91508c908190840183828082843760009201829052506040805163cba510a960e01b81526001600160401b038a16600482015290519596509094611003945063cba510a9935060248083019350602092829003018186803b1580156111c057600080fd5b505afa1580156111d4573d6000803e3d6000fd5b505050506040513d60208110156111ea57600080fd5b505160408051808201909152600381526269626360e81b6020820152909150611217908290898686613f1d565b611260576040805162461bcd60e51b8152602060048201526015602482015274696e76616c6964206d65726b6c652070726f6f663160581b604482015290519081900360640190fd5b5050505061126c61401a565b604080516001600160401b038416815260ff83166020820152815133927f039eb91179ffd7d3b6e97f8ea106e748e827f910b872375dbc9c14a362319c3c928290030190a2505050505050505050505050505050565b603281565b600d6020526000908152604090205461ffff1681565b600e6020526000908152604090205460ff1681565b60045460070b81565b60025481565b600a602052600090815260409020546001600160401b031681565b60606000825160210190506060816040519080825280601f01601f191660200182016040528015611354576020820181803683370190505b506021810186905260018101879052828152905060418101600061137786614098565b509050611386818388516140a2565b50909695505050505050565b600181565b60096020526000908152604090205460ff1681565b61100181565b603881565b600881565b61200081565b604080517710d05390d15317d514905394d1915497d41493d413d4d05360421b8152905190819003601801902081565b60005460ff16611437576040805162461bcd60e51b815260206004820152601960248201526000805160206149b2833981519152604482015290519081900360640190fd5b6040805163569e4ed360e11b815233600482015290516000916110009163ad3c9da691602480820192602092909190829003018186803b15801561147a57600080fd5b505afa15801561148e573d6000803e3d6000fd5b505050506040513d60208110156114a457600080fd5b505160408051633d42651560e11b8152905191925060009161100091637a84ca2a916004808301926020929190829003018186803b1580156114e557600080fd5b505afa1580156114f9573d6000803e3d6000fd5b505050506040513d602081101561150f57600080fd5b505190508061151c575060155b60008211801561152c5750808211155b61156b576040805162461bcd60e51b815260206004820152600b60248201526a1b9bdd0818d8589a5b995d60aa1b604482015290519081900360640190fd5b604080516001600160a01b038087166020808401919091529086168284015282518083038401815260608301808552815191909201207710d05390d15317d514905394d1915497d41493d413d4d05360421b90915291519081900360780190206000906115d890836140e3565b9050801561164a5760408051630911a2c160e11b81526001600160a01b03888116600483015287166024820152905161100491631223458291604480830192600092919082900301818387803b15801561163157600080fd5b505af1158015611645573d6000803e3d6000fd5b505050505b505050505050565b604080516f14d554d411539117d41493d413d4d05360821b8152905190819003601001902081565b600281565b600c602052600090815260409020805460019091015461ffff8216916201000090046001600160801b03169083565b604080516e149153d4115397d41493d413d4d053608a1b8152905190819003600f01902081565b6005602052600090815260409020546001600160a01b031681565b61100581565b601081565b60035481565b61100881565b600b81565b60005460ff16611751576040805162461bcd60e51b815260206004820152601960248201526000805160206149b2833981519152604482015290519081900360640190fd5b60408051630a83aaa960e31b815233600482015290516110069163541d5548916024808301926020929190829003018186803b15801561179057600080fd5b505afa1580156117a4573d6000803e3d6000fd5b505050506040513d60208110156117ba57600080fd5b505161180d576040805162461bcd60e51b815260206004820152601f60248201527f746865206d73672073656e646572206973206e6f7420612072656c6179657200604482015290519081900360640190fd5b60ff8116600090815260086020526040902054829082906001600160401b03908116908316811461187d576040805162461bcd60e51b815260206004820152601560248201527439b2b8bab2b731b2903737ba1034b71037b93232b960591b604482015290519081900360640190fd5b60ff8216600090815260086020908152604091829020805467ffffffffffffffff1916600185016001600160401b039081169190911790915582516337d7f9c160e21b81529089166004820152915188926110039263df5fe70492602480840193829003018186803b1580156118f257600080fd5b505afa158015611906573d6000803e3d6000fd5b505050506040513d602081101561191c57600080fd5b50516119595760405162461bcd60e51b81526004018080602001828103825260238152602001806149d26023913960400191505060405180910390fd5b60ff851660009081526005602052604090205485906001600160a01b03166119c3576040805162461bcd60e51b815260206004820152601860248201527718da185b9b995b081a5cc81b9bdd081cdd5c1c1bdc9d195960421b604482015290519081900360640190fd5b60ff86166000908152600a6020526040902054889087906001600160401b039081169083161015611a2c576040805162461bcd60e51b815260206004820152600e60248201526d3a37b79037b632103432b0b232b960911b604482015290519081900360640190fd5b60ff81166000908152600a60205260409020546001600160401b03838116911614611a7e5760ff81166000908152600a60205260409020805467ffffffffffffffff19166001600160401b0384161790555b600b5460ff1615611ac2576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b60608e8e8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050905060608d8d8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509050611c066110036001600160a01b031663cba510a98e6040518263ffffffff1660e01b815260040180826001600160401b03166001600160401b0316815260200191505060206040518083038186803b158015611baf57600080fd5b505afa158015611bc3573d6000803e3d6000fd5b505050506040513d6020811015611bd957600080fd5b505160408051808201909152600381526269626360e81b6020820152611bff8e8e613ed5565b8585613f1d565b611c4e576040805162461bcd60e51b815260206004820152601460248201527334b73b30b634b21036b2b935b63290383937b7b360611b604482015290519081900360640190fd5b60408051631bb5062960e31b81526001600160401b038e16600482015290516000916110039163dda8314891602480820192602092909190829003018186803b158015611c9a57600080fd5b505afa158015611cae573d6000803e3d6000fd5b505050506040513d6020811015611cc457600080fd5b505190508b8b600080806060611cd9896143c8565b935093509350935083611d9b578460ff16866001600160401b03167ff7b2e42d694eb1100184aae86d4245d9e46966100b1dc7e723275b98326854ac8b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015611d53578181015183820152602001611d3b565b50505050905090810190601f168015611d805780820380516001836020036101000a031916815260200191505b509250505060405180910390a35050505050505050506129b6565b6040805160ff85811682529151918716916001600160401b038916917f36afdaf439a8f43fe72135135d804ae620b37a474f0943b5b85f6788312cad40919081900360200190a360ff83166123205760ff85166000818152600560209081526040808320548151631182b87560e01b815260048101958652602481019283528651604482015286516001600160a01b03909216958695631182b875958d958a9593949093606490910192918601918190849084905b83811015611e68578181015183820152602001611e50565b50505050905090810190601f168015611e955780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b158015611eb557600080fd5b505af1925050508015611f9957506040513d6000823e601f3d908101601f191682016040526020811015611ee857600080fd5b8101908080516040519392919084600160201b821115611f0757600080fd5b908301906020820185811115611f1c57600080fd5b8251600160201b811182820188101715611f3557600080fd5b82525081516020918201929091019080838360005b83811015611f62578181015183820152602001611f4a565b50505050905090810190601f168015611f8f5780820380516001836020036101000a031916815260200191505b5060405250505060015b6122ab576040516000815260443d1015611fb557506000612050565b60046000803e60005160e01c6308c379a08114611fd6576000915050612050565b60043d036004833e81513d60248201116001600160401b038211171561200157600092505050612050565b80830180516001600160401b03811115612022576000945050505050612050565b8060208301013d860181111561204057600095505050505050612050565b601f01601f191660405250925050505b8061205b575061216d565b60ff8716600090815260076020526040812054612092916001600160401b0390911690899061208d906002908861131c565b614478565b60ff8716600090815260076020908152604080832080546001600160401b038082166001011667ffffffffffffffff19909116179055805182815284518184015284516001600160a01b038716947ff91a8f63e5b3e0e89e5f93e1915a7805f3c52d9a73b3c09769785c2c7bf87acf948794849390840192918601918190849084905b8381101561212d578181015183820152602001612115565b50505050905090810190601f16801561215a5780820380516001836020036101000a031916815260200191505b509250505060405180910390a2506122a6565b3d808015612197576040519150601f19603f3d011682016040523d82523d6000602084013e61219c565b606091505b5060ff87166000908152600760205260408120546121cf916001600160401b0390911690899061208d906002908861131c565b60ff8716600090815260076020908152604080832080546001600160401b038082166001011667ffffffffffffffff19909116179055805182815284518184015284516001600160a01b038716947f63ac299d6332d1cc4e61b81e59bc00c0ac7c798addadf33840f1307cd2977351948794849390840192918601918190849084905b8381101561226a578181015183820152602001612252565b50505050905090810190601f1680156122975780820380516001836020036101000a031916815260200191505b509250505060405180910390a2505b61231a565b8051156123185760ff87166000908152600760205260408120546122e4916001600160401b0390911690899061208d906001908661131c565b60ff8716600090815260076020526040902080546001600160401b038082166001011667ffffffffffffffff199091161790555b505b506128ee565b60ff8316600114156125c45760ff8516600081815260056020908152604080832054815163831d65d160e01b815260048101958652602481019283528651604482015286516001600160a01b0390921695869563831d65d1958d958a9593949093606490910192918601918190849084905b838110156123aa578181015183820152602001612392565b50505050905090810190601f1680156123d75780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b1580156123f757600080fd5b505af1925050508015612408575060015b61231a576040516000815260443d1015612424575060006124bf565b60046000803e60005160e01c6308c379a081146124455760009150506124bf565b60043d036004833e81513d60248201116001600160401b0382111715612470576000925050506124bf565b80830180516001600160401b038111156124915760009450505050506124bf565b8060208301013d86018111156124af576000955050505050506124bf565b601f01601f191660405250925050505b806124ca575061252f565b60408051602080825283518183015283516001600160a01b038616937ff91a8f63e5b3e0e89e5f93e1915a7805f3c52d9a73b3c09769785c2c7bf87acf938693909283928301918501908083836000831561212d578181015183820152602001612115565b3d808015612559576040519150601f19603f3d011682016040523d82523d6000602084013e61255e565b606091505b5060408051602080825283518183015283516001600160a01b038616937f63ac299d6332d1cc4e61b81e59bc00c0ac7c798addadf33840f1307cd2977351938693909283928301918501908083836000831561226a578181015183820152602001612252565b60ff8316600214156128ee5760ff8516600081815260056020908152604080832054815163c8509d8160e01b815260048101958652602481019283528651604482015286516001600160a01b0390921695869563c8509d81958d958a9593949093606490910192918601918190849084905b8381101561264e578181015183820152602001612636565b50505050905090810190601f16801561267b5780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b15801561269b57600080fd5b505af19250505080156126ac575060015b6128ec576040516000815260443d10156126c857506000612763565b60046000803e60005160e01c6308c379a081146126e9576000915050612763565b60043d036004833e81513d60248201116001600160401b038211171561271457600092505050612763565b80830180516001600160401b03811115612735576000945050505050612763565b8060208301013d860181111561275357600095505050505050612763565b601f01601f191660405250925050505b8061276e5750612817565b816001600160a01b03167ff91a8f63e5b3e0e89e5f93e1915a7805f3c52d9a73b3c09769785c2c7bf87acf826040518080602001828103825283818151815260200191508051906020019080838360005b838110156127d75781810151838201526020016127bf565b50505050905090810190601f1680156128045780820380516001836020036101000a031916815260200191505b509250505060405180910390a2506128ec565b3d808015612841576040519150601f19603f3d011682016040523d82523d6000602084013e612846565b606091505b50816001600160a01b03167f63ac299d6332d1cc4e61b81e59bc00c0ac7c798addadf33840f1307cd2977351826040518080602001828103825283818151815260200191508051906020019080838360005b838110156128b0578181015183820152602001612898565b50505050905090810190601f1680156128dd5780820380516001836020036101000a031916815260200191505b509250505060405180910390a2505b505b60ff80861660009081526009602052604090205461100591636f93d2e6918a91339187911680612920575060ff881615155b604080516001600160e01b031960e088901b1681526001600160a01b039586166004820152939094166024840152604483019190915215156064820152905160848083019260209291908290030181600087803b15801561298057600080fd5b505af1158015612994573d6000803e3d6000fd5b505050506040513d60208110156129aa57600080fd5b50505050505050505050505b5050505050505050505050505050565b630100380081565b600981565b61100781565b61100681565b60005460ff1681565b3361100714612a285760405162461bcd60e51b815260040180806020018281038252602e815260200180614908602e913960400191505060405180910390fd5b600b5460ff1615612a6c576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b612ad584848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526012815271626174636853697a65466f724f7261636c6560701b602082015291506146129050565b15612b7057604080516020601f8401819004810282018101909252828152600091612b18918585808385018382808284376000920191909152506146f992505050565b90506127108111158015612b2d5750600a8110155b612b685760405162461bcd60e51b81526004018080602001828103825260328152602001806149806032913960400191505060405180910390fd5b60015561341a565b612bd984848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601281527118591913dc955c19185d1950da185b9b995b60721b602082015291506146129050565b15612d6157606082828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505082519293505060169091149050612c5c5760405162461bcd60e51b815260040180806020018281038252605a815260200180614821605a913960600191505060405180910390fd5b60018101516002820151601683015160ff82161590612c7a816146fe565b612ccb576040805162461bcd60e51b815260206004820152601960248201527f61646472657373206973206e6f74206120636f6e747261637400000000000000604482015290519081900360640190fd5b60ff8416600081815260056020908152604080832080546001600160a01b0319166001600160a01b038716908117909155808452600683528184208585528352818420805460ff199081166001179091556009909352818420805490931687151517909255519092917f7e3b6af43092577ee20e60eaa1d9b114a7031305c895ee7dd3ffe17196d2e1e091a3505050505061341a565b612dce84848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526016815275195b98589b1953dc911a5cd8589b1950da185b9b995b60521b602082015291506146129050565b15612eff57606082828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505082519293505060029091149050612e515760405162461bcd60e51b815260040180806020018281038252604a815260200180614936604a913960600191505060405180910390fd5b600181810151600283015160ff80831660009081526005602052604090205492939192908316909114906001600160a01b03168015612ef5576001600160a01b038116600090815260066020908152604080832060ff881680855290835292819020805460ff1916861515908117909155815190815290517fa3132e3f9819fbddc7f0ed6d38d7feef59aa95112090b7c592f5cb5bc4aa4adc929181900390910190a25b505050505061341a565b612f6384848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600d81526c73757370656e6451756f72756d60981b602082015291506146129050565b156130985760028114612fa75760405162461bcd60e51b815260040180806020018281038252602d8152602001806148af602d913960400191505060405180910390fd5b6000612fea600284848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506146f992505050565b905060008161ffff16118015613004575060648161ffff16105b61304e576040805162461bcd60e51b8152602060048201526016602482015275696e76616c69642073757370656e642071756f72756d60501b604482015290519081900360640190fd5b604080516f14d554d411539117d41493d413d4d05360821b815281519081900360100190206000908152600d60205220805461ffff90921661ffff1990921691909117905561341a565b6130fb84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600c81526b72656f70656e51756f72756d60a01b602082015291506146129050565b1561322e576002811461313f5760405162461bcd60e51b815260040180806020018281038252602c8152602001806148dc602c913960400191505060405180910390fd5b6000613182600284848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506146f992505050565b905060008161ffff1611801561319c575060648161ffff16105b6131e5576040805162461bcd60e51b8152602060048201526015602482015274696e76616c69642072656f70656e2071756f72756d60581b604482015290519081900360640190fd5b604080516e149153d4115397d41493d413d4d053608a1b8152815190819003600f0190206000908152600d60205220805461ffff90921661ffff1990921691909117905561341a565b61329984848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601481527363616e63656c5472616e7366657251756f72756d60601b602082015291506146129050565b156133dd57600281146132dd5760405162461bcd60e51b815260040180806020018281038252603481526020018061487b6034913960400191505060405180910390fd5b6000613320600284848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506146f992505050565b905060008161ffff1611801561333a575060648161ffff16105b61338b576040805162461bcd60e51b815260206004820152601e60248201527f696e76616c69642063616e63656c207472616e736665722071756f72756d0000604482015290519081900360640190fd5b604080517710d05390d15317d514905394d1915497d41493d413d4d05360421b815281519081900360180190206000908152600d60205220805461ffff90921661ffff1990921691909117905561341a565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b6008602052600090815260409020546001600160401b031681565b7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081565b61100281565b60005460ff16613536576040805162461bcd60e51b815260206004820152601960248201526000805160206149b2833981519152604482015290519081900360640190fd5b6040805163569e4ed360e11b815233600482015290516000916110009163ad3c9da691602480820192602092909190829003018186803b15801561357957600080fd5b505afa15801561358d573d6000803e3d6000fd5b505050506040513d60208110156135a357600080fd5b505160408051633d42651560e11b8152905191925060009161100091637a84ca2a916004808301926020929190829003018186803b1580156135e457600080fd5b505afa1580156135f8573d6000803e3d6000fd5b505050506040513d602081101561360e57600080fd5b505190508061361b575060155b60008211801561362b5750808211155b61366a576040805162461bcd60e51b815260206004820152600b60248201526a1b9bdd0818d8589a5b995d60aa1b604482015290519081900360640190fd5b600b5460ff166136b1576040805162461bcd60e51b815260206004820152600d60248201526c1b9bdd081cdd5cdc195b991959609a1b604482015290519081900360640190fd5b604080516e149153d4115397d41493d413d4d053608a1b8152905190819003600f019020600090613702907fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4706140e3565b9050801561374057600b805460ff1916905560405133907f899fe8c37dc61708a3aaa99c4bf143346c1d1da69af79be9e8920c0a6785b75290600090a25b505050565b600660209081526000928352604080842090915290825290205460ff1681565b6040518060400160405280600381526020016269626360e81b81525081565b610e1081565b61100381565b60005460ff16156137e8576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b7f1471eb6eb2c5e789fc3de43f8ce62938c7d1836ec861730447e2ada8fd81017b80546001600160a01b0319908116611008179091557f92e85d02570a8092d09a6e3a57665bc3815a2699a4074001bf1ccabf660f5a36805460ff199081169091557fd8af288fc1c8680b4f4706064cf021e264efb6828fcaf7eb5ca36818eb365bcc8054821660019081179091557f89832631fb3c3307a103ba2c84ab569c64d6182a18893dcd163f0f1c2090733a805484166110049081179091557f6cde3cea4b3a3fb2488b2808bae7556f4a405e50f65e1794383bc026131b13c38054841690557f72e4efa1513b071517c6c74dba31b5934a81aa83cddd400e7081df5529c9943680548416831790557fa9bc9a3a348c357ba16b37005d7e6b3236198c0e939f4af8c5f19b8deeb8ebc08054851690911790557fc575c31fea594a6eb97c8e9d3f9caee4c16218c6ef37e923234c0fe9014a61e78054831690557f4e523af77f034e9810f1c94057f5e931fb3d16a51511a4c3add793617d18610580548316821790557ffb33122aa9f93cc639ebe80a7bc4784c11e6053dde89c6f4f7e268c6a623da1e805484166110001790557fc7694af312c4f286114180fd0ba6a52461fcee8a381636770b19a343af92538a80548316821790557f01112dd68e482ba8d68a7e828cff8b3abcea08eab88941953c180a7e650e9cd480548316821790557fc0a4a8be475dfebc377ebef2d7c4ff47656f572a08dd92b81017efcdba0febe1805484166110071790557f87e8a52529e8ece4ef759037313542a6429ff494a9fab9027fb79db90124eba680548316821790557f4c7666bbcb22d46469f7cc282f70764a7012dca2cce630ff8d83db9a9cdd48f080548316821790557f40f28f99a40bc9f6beea1013afdbc3cdcc689eb76b82c4de06c0acf1e1932ed58054909316611001179092557f0d9cf2cd531699eed8dd34e40ff2884a14a698c4898184fba85194e6f6772d248054821683179055600b60009081527f23f68c9bd22b8a93d06adabe17481c87c016bcbd20adc8bfd707a4d813a572176020527fdf0d5d05428057f5455c2dc8e810dd86d1e9350faa72f16bda8a45443c5b39328054831684179055603283556004805467ffffffffffffffff19166001600160401b031790556002819055600381905580549091169091179055565b6007602052600090815260409020546001600160401b031681565b60005460ff16613ba7576040805162461bcd60e51b815260206004820152601960248201526000805160206149b2833981519152604482015290519081900360640190fd5b6040805163569e4ed360e11b815233600482015290516000916110009163ad3c9da691602480820192602092909190829003018186803b158015613bea57600080fd5b505afa158015613bfe573d6000803e3d6000fd5b505050506040513d6020811015613c1457600080fd5b505160408051633d42651560e11b8152905191925060009161100091637a84ca2a916004808301926020929190829003018186803b158015613c5557600080fd5b505afa158015613c69573d6000803e3d6000fd5b505050506040513d6020811015613c7f57600080fd5b5051905080613c8c575060155b600082118015613c9c5750808211155b613cdb576040805162461bcd60e51b815260206004820152600b60248201526a1b9bdd0818d8589a5b995d60aa1b604482015290519081900360640190fd5b600b5460ff1615613d1f576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b604080516f14d554d411539117d41493d413d4d05360821b81529051908190036010019020600090613d71907fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4706140e3565b905080156137405761374061401a565b60005460ff16613dc6576040805162461bcd60e51b815260206004820152601960248201526000805160206149b2833981519152604482015290519081900360640190fd5b33600090815260066020908152604080832060ff8089168552925290912054859116613e235760405162461bcd60e51b81526004018080602001828103825260318152602001806147f06031913960400191505060405180910390fd5b60ff85166000908152600760209081526040808320548151601f88018490048402810184019092528682526001600160401b031692613e889284928a9261208d92909189918c908c908190840183828082843760009201919091525061131c92505050565b60ff959095166000908152600760205260409020805467ffffffffffffffff191660019096016001600160401b03169590951790945550505050565b61100081565b600381565b61100481565b60408051600e808252818301909252606091630100380060ff851617918391602082018180368337505050600e81810187905260068201939093529182525090505b92915050565b600085613f2c57506000614011565b606082518451865160800101016040519080825280601f01601f191660200182016040528015613f63576020820181803683370190505b5090506000613f7182614704565b602080890151825201905086600080613f8989614098565b8086526020909501949092509050613fa28285836140a2565b92830192613faf88614098565b8086526020909501949092509050613fc88285836140a2565b9283018a815260200192613fdb87614098565b9092509050613feb8285836140a2565b508351602001613ff961470a565b60208183886065600019fa5051600114955050505050505b95945050505050565b600b5460ff161561405e576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b600b805460ff1916600117905560405133907f6f123d3d54c84a7960a573b31c221dcd86e13fd849c5adb0c6ca851468cc1ae490600090a2565b8051602090910191565b5b602081106140c2578251825260209283019290910190601f19016140a3565b915181516020939093036101000a6000190180199091169216919091179052565b6000828152600d602052604081205461ffff166141ac57604080516f14d554d411539117d41493d413d4d05360821b815281519081900360100181206000908152600d6020818152848320805461ffff199081166001179091556e149153d4115397d41493d413d4d053608a1b8552855194859003600f01852084528282528584208054821660029081179091557710d05390d15317d514905394d1915497d41493d413d4d05360421b8652865195869003601801909520845291905292902080549092161790555b6000838152600c6020526040902080546201000090046001600160801b0316421015806141dd575082816001015414155b156142b0576000848152600d602090815260409182902054835461ffff90911661ffff199091161771ffffffffffffffffffffffffffffffff0000191662010000610e1042016001600160801b0316021783556001808401869055825191820190925233815261425291600284019190614728565b5080546040805161ffff83168152620100009092046001600160801b0316602083015281810185905251339186917f9e109f0e55ef32e99e4880be2ec357f1ddb3469c79d0747ef4762da6e89fabe5916060908290030190a3614364565b60005b600282015481101561433b57336001600160a01b03168260020182815481106142d857fe5b6000918252602090912001546001600160a01b03161415614333576040805162461bcd60e51b815260206004820152601060248201526f185b1c9958591e48185c1c1c9bdd995960821b604482015290519081900360640190fd5b6001016142b3565b50600281018054600181018255600091825260209091200180546001600160a01b031916331790555b8054600282015461ffff909116116143be576000848152600c60205260408120805471ffffffffffffffffffffffffffffffffffff1916815560018101829055906143b2600283018261478d565b50506001915050613f17565b5060009392505050565b600080600060606021855110156143f8575050604080516000808252602082019092529092508291508190614471565b600185015160218601518651604080516020198301808252601f1960011990940193909316810160200190915260418901939291606091908015614443576020820181803683370190505b509050600061445182614098565b509050614463858260218d51036140a2565b506001975091955093509150505b9193509193565b600b5460ff16156144bc576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b6002544311156144fb576004805467ffffffffffffffff1981166001600160401b036001600793840b810190930b16179091556003554360025561453c565b6003805460019081019182905554101561453c576004805467ffffffffffffffff1981166001600160401b036001600793840b810190930b16179091556003555b8160ff16836001600160401b0316600460009054906101000a900460070b6001600160401b03167f3a6e0fc61675aa2a100bcba0568368bb92bcec91c97673391074f11138f0cffe603885604051808361ffff1661ffff16815260200180602001828103825283818151815260200191508051906020019080838360005b838110156145d25781810151838201526020016145ba565b50505050905090810190601f1680156145ff5780820380516001836020036101000a031916815260200191505b50935050505060405180910390a4505050565b6000816040516020018082805190602001908083835b602083106146475780518252601f199092019160209182019101614628565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b602083106146b55780518252601f199092019160209182019101614696565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b015190565b3b151590565b60200190565b60405180602001604052806001906020820280368337509192915050565b82805482825590600052602060002090810192821561477d579160200282015b8281111561477d57825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190614748565b506147899291506147ae565b5090565b50805460008255906000526020600020908101906147ab91906147d5565b50565b6147d291905b808211156147895780546001600160a01b03191681556001016147b4565b90565b6147d291905b8082111561478957600081556001016147db56fe74686520636f6e747261637420616e64206368616e6e656c2068617665206e6f74206265656e20726567697374657265646c656e677468206f662076616c756520666f72206164644f725570646174654368616e6e656c2073686f756c642062652032322c206368616e6e656c49643a697346726f6d53797374656d3a68616e646c6572416464726573736c656e677468206f662076616c756520666f722063616e63656c5472616e7366657251756f72756d2073686f756c6420626520326c656e677468206f662076616c756520666f722073757370656e6451756f72756d2073686f756c6420626520326c656e677468206f662076616c756520666f722072656f70656e51756f72756d2073686f756c642062652032746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e74726163746c656e677468206f662076616c756520666f7220656e61626c654f7244697361626c654368616e6e656c2073686f756c6420626520322c206368616e6e656c49643a6973456e61626c65746865206e6577426174636853697a65466f724f7261636c652073686f756c6420626520696e205b31302c2031303030305d74686520636f6e7472616374206e6f7420696e697420796574000000000000006c6967687420636c69656e74206e6f742073796e632074686520626c6f636b20796574a2646970667358221220622dd2ff8c5505e7bf8251c7cfe63da6bfa7891c3682ca46b6d6bf796895609f64736f6c63430006040033", + }, + }, + } + + lubanUpgrade[chapelNet] = &Upgrade{ + UpgradeName: "luban", + Configs: []*UpgradeConfig{ + { + ContractAddr: common.HexToAddress(ValidatorContract), + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/b144718e94d7a1ebb24a7103202300f08826f369", + Code: "60806040526004361061046c5760003560e01c8063862498821161024a578063c6d3394511610139578063e40716a1116100b6578063f9a2bbc71161007a578063f9a2bbc714610b6b578063fc3e590814610b80578063fccc281314610b95578063fd4ad81f14610baa578063fd6a687914610bd957610473565b8063e40716a114610af9578063eb57e20214610b0e578063eda5868c14610b2e578063f340fa0114610b43578063f92eb86b14610b5657610473565b8063d86222d5116100fd578063d86222d514610a90578063daacdb6614610aa5578063dc927faf14610aba578063e086c7b114610acf578063e1c7392a14610ae457610473565b8063c6d3394514610a3c578063c81b166214610a51578063c8509d811461085f578063d04aa99614610a66578063d68fb56a14610a7b57610473565b8063a5422d5c116101c7578063ad3c9da61161018b578063ad3c9da6146109d0578063aef198a9146109f0578063b7ab4db514610a05578063b8cf4ef114610a27578063bf9f49951461062f57610473565b8063a5422d5c1461095c578063a78abc1614610971578063aaf5eb6814610986578063ab51bb961461099b578063ac431751146109b057610473565b806396713da91161020e57806396713da9146108f35780639dc09262146109085780639fe0f8161461091d578063a0dc275814610932578063a1a11bf51461094757610473565b8063862498821461087f57806388b32f11146108945780638b5ad0c9146108a95780638d19a410146108be5780639369d7de146108de57610473565b80634df6e0c3116103665780636e47b482116102e35780637942fd05116102a75780637942fd05146108205780637a84ca2a1461083557806381650b621461084a578063831d65d11461085f578063853230aa1461080b57610473565b80636e47b482146107b757806370fd5bad146107cc578063718a8aa8146107e157806375d47a0a146107f657806378dfed4a1461080b57610473565b8063565c56b31161032a578063565c56b3146107265780635667515a146107465780635d77156c1461075b57806362b72cf5146107705780636969a25c1461078557610473565b80634df6e0c3146106b25780635192c82c146106c757806351e80672146106dc578063549b03f2146106f157806355614fcc1461070657610473565b8063321d398a116103f45780633dffc387116103b85780633dffc3871461062f57806343756e5c1461065157806345cf9daf14610666578063493279b11461067b5780634bf6c8821461069d57610473565b8063321d398a146105975780633365af3a146105b757806335409f7f146105d75780633b071dcc146105f75780633de0f0d81461061a57610473565b80631182b8751161043b5780631182b875146104fe578063152ad3b81461052b5780631ff180691461054d578063219f22d514610562578063300c35671461057757610473565b806304c4fec61461047857806307a568471461048f5780630bee7a67146104ba5780630e2374a5146104dc57610473565b3661047357005b600080fd5b34801561048457600080fd5b5061048d610bee565b005b34801561049b57600080fd5b506104a4610c60565b6040516104b19190616ef0565b60405180910390f35b3480156104c657600080fd5b506104cf610c66565b6040516104b19190616f1a565b3480156104e857600080fd5b506104f1610c6b565b6040516104b191906162f7565b34801561050a57600080fd5b5061051e6105193660046161dd565b610c71565b6040516104b1919061646e565b34801561053757600080fd5b50610540610ea9565b6040516104b19190616463565b34801561055957600080fd5b506104a4610eb2565b34801561056e57600080fd5b506104cf610eb8565b34801561058357600080fd5b5061048d6105923660046160a6565b610ebd565b3480156105a357600080fd5b506105406105b236600461618a565b611241565b3480156105c357600080fd5b506105406105d236600461618a565b611310565b3480156105e357600080fd5b5061048d6105f236600461607f565b6113c1565b34801561060357600080fd5b5061060c61151a565b6040516104b1929190616379565b34801561062657600080fd5b506104a46117f6565b34801561063b57600080fd5b506106446117fc565b6040516104b19190616f2b565b34801561065d57600080fd5b506104f1611801565b34801561067257600080fd5b506104a4611807565b34801561068757600080fd5b5061069061180d565b6040516104b19190616ee1565b3480156106a957600080fd5b50610644611812565b3480156106be57600080fd5b5061060c611817565b3480156106d357600080fd5b506104a4611995565b3480156106e857600080fd5b506104f161199b565b3480156106fd57600080fd5b506104a46119a1565b34801561071257600080fd5b5061054061072136600461607f565b6119a7565b34801561073257600080fd5b506104a461074136600461607f565b6119dc565b34801561075257600080fd5b50610644611a2d565b34801561076757600080fd5b506104cf611a32565b34801561077c57600080fd5b506104a4611a37565b34801561079157600080fd5b506107a56107a036600461618a565b611a3d565b6040516104b196959493929190616324565b3480156107c357600080fd5b506104f1611aa1565b3480156107d857600080fd5b50610644611aa7565b3480156107ed57600080fd5b50610644611aac565b34801561080257600080fd5b506104f1611ab1565b34801561081757600080fd5b506104a4611ab7565b34801561082c57600080fd5b50610644611abd565b34801561084157600080fd5b506104a4611ac2565b34801561085657600080fd5b506104cf611ac8565b34801561086b57600080fd5b5061048d61087a3660046161dd565b611acd565b34801561088b57600080fd5b506104a4611b2e565b3480156108a057600080fd5b506104a4611b34565b3480156108b557600080fd5b506104a4611b3a565b3480156108ca57600080fd5b506104a46108d936600461607f565b611b40565b3480156108ea57600080fd5b5061048d611b80565b3480156108ff57600080fd5b50610644611c94565b34801561091457600080fd5b506104f1611c99565b34801561092957600080fd5b506104a4611c9f565b34801561093e57600080fd5b506104a4611ca4565b34801561095357600080fd5b506104f1611ca9565b34801561096857600080fd5b5061051e611caf565b34801561097d57600080fd5b50610540611cce565b34801561099257600080fd5b506104a4611cd7565b3480156109a757600080fd5b506104cf611a2d565b3480156109bc57600080fd5b5061048d6109cb36600461612e565b611ce0565b3480156109dc57600080fd5b506104a46109eb36600461607f565b61258c565b3480156109fc57600080fd5b506104a461259e565b348015610a1157600080fd5b50610a1a6125ab565b6040516104b19190616366565b348015610a3357600080fd5b506104a4612697565b348015610a4857600080fd5b506104a4611aa7565b348015610a5d57600080fd5b506104f161269c565b348015610a7257600080fd5b506104a46126a2565b348015610a8757600080fd5b506104a46126a7565b348015610a9c57600080fd5b506104a46126e6565b348015610ab157600080fd5b506104a46126f2565b348015610ac657600080fd5b506104f16126f8565b348015610adb57600080fd5b506104a46126fe565b348015610af057600080fd5b5061048d612703565b348015610b0557600080fd5b506104a46128b2565b348015610b1a57600080fd5b5061048d610b2936600461607f565b6128b8565b348015610b3a57600080fd5b506104cf6129c0565b61048d610b5136600461607f565b6129c5565b348015610b6257600080fd5b506104a4612c4d565b348015610b7757600080fd5b506104f1612c53565b348015610b8c57600080fd5b50610644611c9f565b348015610ba157600080fd5b506104f1612c59565b348015610bb657600080fd5b50610bca610bc536600461618a565b612c5f565b6040516104b193929190616ef9565b348015610be557600080fd5b506104f1612d21565b6000610bf933611b40565b9050600b8181548110610c0857fe5b600091825260209091206001601690920201015460ff16610c445760405162461bcd60e51b8152600401610c3b90616b99565b60405180910390fd5b6000610c4e6126a7565b9050610c5b338383612d27565b505050565b60095481565b606481565b61200181565b60005460609060ff16610c965760405162461bcd60e51b8152600401610c3b9061662d565b3361200014610cb75760405162461bcd60e51b8152600401610c3b90616d78565b600b54610d7557610cc6615d6b565b60015460005b81811015610d7157600b8054600181018255600091909152835160008051602061714e833981519152601690920291820190815560208086015160008051602061718e8339815191528401805460ff1916911515919091179055604086015180518794610d4d9360008051602061716e833981519152909101920190615d9a565b506060820151610d639060038301906013615e14565b505050806001019050610ccc565b5050505b610d7d615e41565b6000610dbe85858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612f1392505050565b9150915080610dda57610dd160646130cf565b92505050610ea2565b815160009060ff16610dff57610df883602001518460400151613130565b9050610e6e565b825160ff1660011415610e6a57826020015151600114610e445760008051602061712e833981519152604051610e3490616a80565b60405180910390a1506067610e65565b610df88360200151600081518110610e5857fe5b6020026020010151613d84565b610e6e565b5060655b63ffffffff8116610e935750506040805160008152602081019091529150610ea29050565b610e9c816130cf565b93505050505b9392505050565b60075460ff1681565b60035481565b606881565b334114610edc5760405162461bcd60e51b8152600401610c3b90616dc7565b6010544311610efd5760405162461bcd60e51b8152600401610c3b90616789565b60005460ff16610f1f5760405162461bcd60e51b8152600401610c3b9061662d565b600f54610f37576032600f5561100231601155611237565b60006110023168056bc75e2d63100000811115610f6657610f5f81606463ffffffff613efb16565b9150610faf565b601154811115610fa857610f5f6064610f9c600f54610f9060115486613f3d90919063ffffffff16565b9063ffffffff613f7f16565b9063ffffffff613efb16565b5050611237565b6040516309a99b4f60e41b815261100290639a99b4f090610fd6903090869060040161630b565b602060405180830381600087803b158015610ff057600080fd5b505af1158015611004573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061102891906161a2565b6110023160115591508161103d575050611237565b6000805b8481101561106b5785858281811061105557fe5b9050602002013582019150806001019050611041565b508061107957505050611237565b6000806000805b8981101561122f578489898381811061109557fe5b905060200201358802816110a557fe5b0493508a8a828181106110b457fe5b90506020020160208101906110c9919061607f565b6001600160a01b038116600090815260046020526040902054909350915081156111e55760006001808403815481106110fe57fe5b9060005260206000209060040201905080600201601c9054906101000a900460ff161561116b57836001600160a01b03167fb9c75cbbfde137c4281689580799ef5f52144e78858f776a5979b2b212137d858660405161115e9190616ef0565b60405180910390a26111df565b60035461117e908663ffffffff613fb916565b6003908155810154611196908663ffffffff613fb916565b60038201556040516001600160a01b038516907fcb0aad6cf9cd03bdf6137e359f541c42f38b39f007cae8e89e88aa7d8c6617b2906111d6908890616ef0565b60405180910390a25b50611227565b826001600160a01b03167fb9c75cbbfde137c4281689580799ef5f52144e78858f776a5979b2b212137d858560405161121e9190616ef0565b60405180910390a25b600101611080565b505050505050505b5050436010555050565b60015460009082106112555750600061130b565b60006001600160a01b03166001838154811061126d57fe5b60009182526020909120600490910201546001600160a01b0316148061129d5750600854158061129d5750600a54155b806112ac575060085460095410155b806112bd57506112bb82611310565b155b806112e657506000600b83815481106112d257fe5b906000526020600020906016020160000154115b806112fa575060016112f66125ab565b5111155b156113075750600061130b565b5060015b919050565b60015460009082106113245750600061130b565b600b548210611361576001828154811061133a57fe5b9060005260206000209060040201600201601c9054906101000a900460ff1615905061130b565b6001828154811061136e57fe5b9060005260206000209060040201600201601c9054906101000a900460ff161580156113bb5750600b82815481106113a257fe5b600091825260209091206001601690920201015460ff16155b92915050565b33611001146113e25760405162461bcd60e51b8152600401610c3b90616e98565b600b546114a0576113f1615d6b565b60015460005b8181101561149c57600b8054600181018255600091909152835160008051602061714e833981519152601690920291820190815560208086015160008051602061718e8339815191528401805460ff19169115159190911790556040860151805187946114789360008051602061716e833981519152909101920190615d9a565b50606082015161148e9060038301906013615e14565b5050508060010190506113f7565b5050505b6001600160a01b038116600090815260046020526040902054806114c45750611517565b6001810390506000600b82815481106114d957fe5b600091825260209091206001601690920201015460ff1690506114fc8383613fde565b80156115055750805b15610c5b576009805460001901905550505b50565b60015460609081906000805b8281101561156d576001818154811061153b57fe5b9060005260206000209060040201600201601c9054906101000a900460ff16611565576001909101905b600101611526565b5060608160405190808252806020026020018201604052801561159a578160200160208202803683370190505b5090506060826040519080825280602002602001820160405280156115d357816020015b60608152602001906001900390816115be5790505b50600b546000945090915084141561174e5760005b8481101561174857600181815481106115fd57fe5b9060005260206000209060040201600201601c9054906101000a900460ff16611740576001818154811061162d57fe5b600091825260209091206004909102015483516001600160a01b039091169084908690811061165857fe5b60200260200101906001600160a01b031690816001600160a01b031681525050600b818154811061168557fe5b600091825260209182902060026016909202018101805460408051601f60001961010060018616150201909316949094049182018590048502840185019052808352919290919083018282801561171d5780601f106116f25761010080835404028352916020019161171d565b820191906000526020600020905b81548152906001019060200180831161170057829003601f168201915b505050505082858151811061172e57fe5b60209081029190910101526001909301925b6001016115e8565b506117ea565b60005b848110156117e8576001818154811061176657fe5b9060005260206000209060040201600201601c9054906101000a900460ff166117e0576001818154811061179657fe5b600091825260209091206004909102015483516001600160a01b03909116908490869081106117c157fe5b6001600160a01b03909216602092830291909101909101526001909301925b600101611751565b505b909450925050505b9091565b61271081565b600181565b61100181565b60085481565b606181565b600881565b600e54600c5460609182918061182b575060155b60606118356125ab565b9050606061184282614391565b9050828251116118595790945092506117f2915050565b8383835103101561186b578282510393505b83156118a15760c8430461188783838388880360008a8a6144ff565b61189f8383838888038989038a8b8b8b5103016144ff565b505b6060836040519080825280602002602001820160405280156118cd578160200160208202803683370190505b50905060608460405190808252806020026020018201604052801561190657816020015b60608152602001906001900390816118f15790505b50905060005b858110156119875784818151811061192057fe5b602002602001015183828151811061193457fe5b60200260200101906001600160a01b031690816001600160a01b03168152505083818151811061196057fe5b602002602001015182828151811061197457fe5b602090810291909101015260010161190c565b509096509450505050509091565b60065481565b61200081565b600f5481565b6001600160a01b038116600090815260046020526040812054806119cf57600091505061130b565b60001901610ea281611310565b6001600160a01b03811660009081526004602052604081205480611a0457600091505061130b565b600180820381548110611a1357fe5b906000526020600020906004020160030154915050919050565b600081565b606781565b60105481565b60018181548110611a4a57fe5b600091825260209091206004909102018054600182015460028301546003909301546001600160a01b0392831694509082169291821691600160a01b81046001600160401b031691600160e01b90910460ff169086565b61100581565b600281565b601081565b61100881565b6103e881565b600b81565b600c5481565b606681565b3361200014611aee5760405162461bcd60e51b8152600401610c3b90616d78565b7f41ce201247b6ceb957dcdb217d0b8acb50b9ea0e12af9af4f5e7f38902101605838383604051611b2193929190616f39565b60405180910390a1505050565b60025481565b60115481565b600a5481565b6001600160a01b03811660009081526004602052604081205480611b765760405162461bcd60e51b8152600401610c3b90616d00565b6000190192915050565b600b54611c3e57611b8f615d6b565b60015460005b81811015611c3a57600b8054600181018255600091909152835160008051602061714e833981519152601690920291820190815560208086015160008051602061718e8339815191528401805460ff1916911515919091179055604086015180518794611c169360008051602061716e833981519152909101920190615d9a565b506060820151611c2c9060038301906013615e14565b505050806001019050611b95565b5050505b600854611c4b5760036008555b600a54611c58576002600a555b6000611c6333611b40565b9050611c6e81611241565b611c8a5760405162461bcd60e51b8152600401610c3b90616a3d565b6115173382614656565b600981565b61100781565b600381565b60c881565b61100681565b604051806101e001604052806101ab8152602001616f836101ab913981565b60005460ff1681565b6402540be40081565b60005460ff16611d025760405162461bcd60e51b8152600401610c3b9061662d565b3361100714611d235760405162461bcd60e51b8152600401610c3b90616b06565b611d8d84848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526013815272065787069726554696d655365636f6e6447617606c1b602082015291506146ee9050565b15611e2a5760208114611db25760405162461bcd60e51b8152600401610c3b90616cba565b604080516020601f8401819004810282018101909252828152600091611df09185858083850183828082843760009201919091525061474792505050565b905060648110158015611e065750620186a08111155b611e225760405162461bcd60e51b8152600401610c3b906168e6565b600255612549565b611e8a84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260098152686275726e526174696f60b81b602082015291506146ee9050565b15611f265760208114611eaf5760405162461bcd60e51b8152600401610c3b906164b3565b604080516020601f8401819004810282018101909252828152600091611eed9185858083850183828082843760009201919091525061474792505050565b9050612710811115611f115760405162461bcd60e51b8152600401610c3b906167cb565b6006556007805460ff19166001179055612549565b611f9084848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260138152726d61784e756d4f664d61696e7461696e696e6760681b602082015291506146ee9050565b1561202a5760208114611fb55760405162461bcd60e51b8152600401610c3b906164ea565b604080516020601f8401819004810282018101909252828152600091611ff39185858083850183828082843760009201919091525061474792505050565b600c5490915080612002575060155b8082106120215760405162461bcd60e51b8152600401610c3b9061683e565b50600855612549565b61209384848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260128152716d61696e7461696e536c6173685363616c6560701b602082015291506146ee9050565b1561212c57602081146120b85760405162461bcd60e51b8152600401610c3b906165b3565b604080516020601f84018190048102820181019092528281526000916120f69185858083850183828082843760009201919091525061474792505050565b90506000811180156121085750600a81105b6121245760405162461bcd60e51b8152600401610c3b90616e14565b600a55612549565b6121a084848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601981527f6d61784e756d4f66576f726b696e6743616e6469646174657300000000000000602082015291506146ee9050565b1561222f57602081146121c55760405162461bcd60e51b8152600401610c3b90616567565b604080516020601f84018190048102820181019092528281526000916122039185858083850183828082843760009201919091525061474792505050565b9050600d548111156122275760405162461bcd60e51b8152600401610c3b9061695c565b600e55612549565b61229884848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260128152716d61784e756d4f6643616e6469646174657360701b602082015291506146ee9050565b1561231a57602081146122bd5760405162461bcd60e51b8152600401610c3b90616b54565b604080516020601f84018190048102820181019092528281526000916122fb9185858083850183828082843760009201919091525061474792505050565b600d819055600e5490915081101561231457600d54600e555b50612549565b61237e84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600d81526c6e756d4f66436162696e65747360981b602082015291506146ee9050565b1561242c57602081146123a35760405162461bcd60e51b8152600401610c3b906165f8565b604080516020601f84018190048102820181019092528281526000916123e19185858083850183828082843760009201919091525061474792505050565b9050600081116124035760405162461bcd60e51b8152600401610c3b9061669b565b60298111156124245760405162461bcd60e51b8152600401610c3b906166e3565b600c55612549565b61249684848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601381527266696e616c697479526577617264526174696f60681b602082015291506146ee9050565b1561253157602081146124bb5760405162461bcd60e51b8152600401610c3b90616c3d565b604080516020601f84018190048102820181019092528281526000916124f99185858083850183828082843760009201919091525061474792505050565b90506001811015801561250d575060648111155b6125295760405162461bcd60e51b8152600401610c3b906169cb565b600f55612549565b60405162461bcd60e51b8152600401610c3b90616e71565b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a8484848460405161257e9493929190616481565b60405180910390a150505050565b60046020526000908152604090205481565b68056bc75e2d6310000081565b6001546060906000805b828110156125da576125c681611310565b156125d2578160010191505b6001016125b5565b50606081604051908082528060200260200182016040528015612607578160200160208202803683370190505b5090506000915060005b8381101561268e5761262281611310565b15612686576001818154811061263457fe5b600091825260209091206004909102015482516001600160a01b039091169083908590811061265f57fe5b60200260200101906001600160a01b031690816001600160a01b0316815250508260010192505b600101612611565b50925050505b90565b601581565b61100281565b603281565b60006126b16125ab565b519050600080600c54116126c65760156126ca565b600c545b9050808211156126d8578091505b816126e257600191505b5090565b67016345785d8a000081565b60055481565b61100381565b602981565b60005460ff16156127265760405162461bcd60e51b8152600401610c3b90616c06565b61272e615e41565b6000612754604051806101e001604052806101ab8152602001616f836101ab9139612f13565b91509150806127755760405162461bcd60e51b8152600401610c3b90616d37565b60005b82602001515181101561289a5760018360200151828151811061279757fe5b60209081029190910181015182546001818101855560009485528385208351600493840290910180546001600160a01b039283166001600160a01b03199182161782558587015182850180549185169183169190911790556040860151600283018054606089015160808a01511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b199590981692909516919091179290921694909417161790915560a09093015160039093019290925591860151805191850193918590811061286d57fe5b602090810291909101810151516001600160a01b0316825281019190915260400160002055600101612778565b50506103e8600255506000805460ff19166001179055565b600d5481565b33611001146128d95760405162461bcd60e51b8152600401610c3b90616e98565b600b54612997576128e8615d6b565b60015460005b8181101561299357600b8054600181018255600091909152835160008051602061714e833981519152601690920291820190815560208086015160008051602061718e8339815191528401805460ff191691151591909117905560408601518051879461296f9360008051602061716e833981519152909101920190615d9a565b5060608201516129859060038301906013615e14565b5050508060010190506128ee565b5050505b60006129a28261474c565b90506129ad81611241565b156129bc576129bc8282614656565b5050565b606581565b3341146129e45760405162461bcd60e51b8152600401610c3b90616dc7565b60005460ff16612a065760405162461bcd60e51b8152600401610c3b9061662d565b60003411612a265760405162461bcd60e51b8152600401610c3b9061692d565b6001600160a01b0381166000908152600460205260409020546007543491906103e89060ff1615612a5657506006545b600083118015612a665750600081115b15612b07576000612a83612710610f9c868563ffffffff613f7f16565b90508015612b055760405161dead9082156108fc029083906000818181858888f19350505050158015612aba573d6000803e3d6000fd5b507f627059660ea01c4733a328effb2294d2f86905bf806da763a89cee254de8bee581604051612aea9190616ef0565b60405180910390a1612b02848263ffffffff613f3d16565b93505b505b8115612c05576000600180840381548110612b1e57fe5b9060005260206000209060040201905080600201601c9054906101000a900460ff1615612b8b57846001600160a01b03167ff177e5d6c5764d79c32883ed824111d9b13f5668cf6ab1cc12dd36791dd955b485604051612b7e9190616ef0565b60405180910390a2612bff565b600354612b9e908563ffffffff613fb916565b6003908155810154612bb6908563ffffffff613fb916565b60038201556040516001600160a01b038616907f93a090ecc682c002995fad3c85b30c5651d7fd29b0be5da9d784a3302aedc05590612bf6908790616ef0565b60405180910390a25b50612c47565b836001600160a01b03167ff177e5d6c5764d79c32883ed824111d9b13f5668cf6ab1cc12dd36791dd955b484604051612c3e9190616ef0565b60405180910390a25b50505050565b600e5481565b61100081565b61dead81565b600b8181548110612c6c57fe5b6000918252602091829020601691909102018054600180830154600280850180546040805161010096831615969096026000190190911692909204601f810188900488028501880190925281845293965060ff90911694919291830182828015612d175780601f10612cec57610100808354040283529160200191612d17565b820191906000526020600020905b815481529060010190602001808311612cfa57829003601f168201915b5050505050905083565b61100481565b6000600a5460001480612d38575081155b80612d435750600954155b15612d5057506000610ea2565b60096000815460019003919050819055506000612d9b600a54610f9c85610f9c600b8981548110612d7d57fe5b6000918252602090912060169091020154439063ffffffff613f3d16565b90506000600b8581548110612dac57fe5b906000526020600020906016020160010160006101000a81548160ff0219169083151502179055506000806110016001600160a01b0316638256ace66040518163ffffffff1660e01b8152600401604080518083038186803b158015612e1157600080fd5b505afa158015612e25573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e4991906161ba565b9150915060009350808310612ec357612e628787613fde565b506040516305bfb49960e41b815261100190635bfb499090612e88908a906004016162f7565b600060405180830381600087803b158015612ea257600080fd5b505af1158015612eb6573d6000803e3d6000fd5b5050505060019350612ed5565b818310612ed557612ed38761474c565b505b6040516001600160a01b038816907fb9d38178dc641ff1817967a63c9078cbcd955a9f1fcd75e0e3636de615d44d3b90600090a25050509392505050565b612f1b615e41565b6000612f25615e41565b612f2d615e65565b612f3e612f39866148ef565b614914565b90506000805b612f4d8361495e565b156130c15780612f7257612f68612f638461497f565b6149cd565b60ff1684526130b9565b80600114156130b4576060612f8e612f898561497f565b614a4d565b90508051604051908082528060200260200182016040528015612fcb57816020015b612fb8615e85565b815260200190600190039081612fb05790505b508560200181905250805160405190808252806020026020018201604052801561300957816020015b6060815260200190600190039081612ff45790505b50604086015260005b81518110156130a957613023615e85565b6060600061304385858151811061303657fe5b6020026020010151614b1e565b92509250925080613063578860009a509a505050505050505050506130ca565b828960200151858151811061307457fe5b6020026020010181905250818960400151858151811061309057fe5b6020026020010181905250505050806001019050613012565b5060019250506130b9565b6130c1565b600101612f44565b50919350909150505b915091565b604080516001808252818301909252606091829190816020015b60608152602001906001900390816130e957905050905061310f8363ffffffff16614c38565b8160008151811061311c57fe5b6020026020010181905250610ea281614c4b565b60006029835111156131675760008051602061712e83398151915260405161315790616740565b60405180910390a15060666113bb565b60005b83518110156132055760005b818110156131fc5784818151811061318a57fe5b6020026020010151600001516001600160a01b03168583815181106131ab57fe5b6020026020010151600001516001600160a01b031614156131f45760008051602061712e8339815191526040516131e19061689b565b60405180910390a16066925050506113bb565b600101613176565b5060010161316a565b506060806132138585614cd5565b60015491935091506000908190815b818110156132985767016345785d8a00006001828154811061324057fe5b9060005260206000209060040201600301541061326257836001019350613290565b60006001828154811061327157fe5b9060005260206000209060040201600301541115613290578260010192505b600101613222565b506060836040519080825280602002602001820160405280156132c5578160200160208202803683370190505b5090506060846040519080825280602002602001820160405280156132f4578160200160208202803683370190505b509050606085604051908082528060200260200182016040528015613323578160200160208202803683370190505b509050606086604051908082528060200260200182016040528015613352578160200160208202803683370190505b5090506000606087604051908082528060200260200182016040528015613383578160200160208202803683370190505b5090506060886040519080825280602002602001820160405280156133b2578160200160208202803683370190505b509050600099506000985060006110046001600160a01b031663149d14d96040518163ffffffff1660e01b815260040160206040518083038186803b1580156133fa57600080fd5b505afa15801561340e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061343291906161a2565b905067016345785d8a000081111561347d5760008051602061712e83398151915260405161345f90616bc5565b60405180910390a160689d50505050505050505050505050506113bb565b60005b898110156136ee5767016345785d8a00006001828154811061349e57fe5b9060005260206000209060040201600301541061362357600181815481106134c257fe5b906000526020600020906004020160020160009054906101000a90046001600160a01b0316898d815181106134f357fe5b60200260200101906001600160a01b031690816001600160a01b03168152505060006402540be4006001838154811061352857fe5b9060005260206000209060040201600301548161354157fe5b066001838154811061354f57fe5b9060005260206000209060040201600301540390506135778382613f3d90919063ffffffff16565b898e8151811061358357fe5b6020026020010181815250506001828154811061359c57fe5b906000526020600020906004020160020160009054906101000a90046001600160a01b0316878e815181106135cd57fe5b60200260200101906001600160a01b031690816001600160a01b03168152505081888e815181106135fa57fe5b6020908102919091010152613615868263ffffffff613fb916565b95508c6001019c50506136e6565b60006001828154811061363257fe5b90600052602060002090600402016003015411156136e6576001818154811061365757fe5b906000526020600020906004020160010160009054906101000a90046001600160a01b0316848c8151811061368857fe5b60200260200101906001600160a01b031690816001600160a01b031681525050600181815481106136b557fe5b906000526020600020906004020160030154838c815181106136d357fe5b6020026020010181815250508a6001019a505b600101613480565b5060008415613964576002546040516303702b2960e51b815261100491636e056520918891613728918e918e918d914201906004016163e9565b6020604051808303818588803b15801561374157600080fd5b505af193505050508015613772575060408051601f3d908101601f1916820190925261376f9181019061610e565b60015b6138e9576040516000815260443d101561378e57506000613829565b60046000803e60005160e01c6308c379a081146137af576000915050613829565b60043d036004833e81513d60248201116001600160401b03821117156137da57600092505050613829565b80830180516001600160401b038111156137fb576000945050505050613829565b8060208301013d860181111561381957600095505050505050613829565b601f01601f191660405250925050505b806138345750613876565b60019150857fa7cdeed7d0db45e3219a6e5d60838824c16f1d39991fcfe3f963029c844bf28082604051613868919061646e565b60405180910390a2506138e4565b3d8080156138a0576040519150601f19603f3d011682016040523d82523d6000602084013e6138a5565b606091505b5060019150857fbfa884552dd8921b6ce90bfe906952ae5b3b29be0cc1a951d4f62697635a3a45826040516138da919061646e565b60405180910390a2505b613964565b801561392b577fa217d08e65f80c73121cd9db834d81652d544bfbf452f6d04922b16c90a37b708660405161391e9190616ef0565b60405180910390a1613962565b857fa7cdeed7d0db45e3219a6e5d60838824c16f1d39991fcfe3f963029c844bf28060405161395990616530565b60405180910390a25b505b8015613b1a5760005b8751811015613b1857600088828151811061398457fe5b6020026020010151905060006001828154811061399d57fe5b60009182526020909120600160049092020181015481546001600160a01b03909116916108fc91859081106139ce57fe5b9060005260206000209060040201600301549081150290604051600060405180830381858888f1935050505090508015613a8a5760018281548110613a0f57fe5b60009182526020909120600160049092020181015481546001600160a01b03909116917f6c61d60f69a7beb3e1c80db7f39f37b208537cbb19da3174511b477812b2fc7d9185908110613a5e57fe5b906000526020600020906004020160030154604051613a7d9190616ef0565b60405180910390a2613b0e565b60018281548110613a9757fe5b60009182526020909120600160049092020181015481546001600160a01b03909116917f25d0ce7d2f0cec669a8c17efe49d195c13455bb8872b65fa610ac7f53fe4ca7d9185908110613ae657fe5b906000526020600020906004020160030154604051613b059190616ef0565b60405180910390a25b505060010161396d565b505b835115613c645760005b8451811015613c62576000858281518110613b3b57fe5b60200260200101516001600160a01b03166108fc868481518110613b5b57fe5b60200260200101519081150290604051600060405180830381858888f1935050505090508015613bf157858281518110613b9157fe5b60200260200101516001600160a01b03167f6c61d60f69a7beb3e1c80db7f39f37b208537cbb19da3174511b477812b2fc7d868481518110613bcf57fe5b6020026020010151604051613be49190616ef0565b60405180910390a2613c59565b858281518110613bfd57fe5b60200260200101516001600160a01b03167f25d0ce7d2f0cec669a8c17efe49d195c13455bb8872b65fa610ac7f53fe4ca7d868481518110613c3b57fe5b6020026020010151604051613c509190616ef0565b60405180910390a25b50600101613b24565b505b5050505050505050505050506000471115613ce0577f6ecc855f9440a9282c90913bbc91619fd44f5ec0b462af28d127b116f130aa4d47604051613ca89190616ef0565b60405180910390a1604051611002904780156108fc02916000818181858888f19350505050158015613cde573d6000803e3d6000fd5b505b60006003819055600555815115613cfb57613cfb8282614f0e565b6110016001600160a01b031663fc4333cd6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015613d3857600080fd5b505af1158015613d4c573d6000803e3d6000fd5b50506040517fedd8d7296956dd970ab4de3f2fc03be2b0ffc615d20cd4c72c6e44f928630ebf925060009150a1506000949350505050565b80516001600160a01b0316600090815260046020526040812054801580613dd55750600180820381548110613db557fe5b9060005260206000209060040201600201601c9054906101000a900460ff165b15613e1b5782516040516001600160a01b03909116907fe209c46bebf57cf265d5d9009a00870e256d9150f3ed5281ab9d9eb3cec6e4be90600090a2600091505061130b565b600154600554600019820111801590613e715784516040516001600160a01b03909116907fe209c46bebf57cf265d5d9009a00870e256d9150f3ed5281ab9d9eb3cec6e4be90600090a26000935050505061130b565b600580546001908101909155805481906000198601908110613e8f57fe5b6000918252602082206002600490920201018054921515600160e01b0260ff60e01b199093169290921790915585516040516001600160a01b03909116917ff226e7d8f547ff903d9d419cf5f54e0d7d07efa9584135a53a057c5f1f27f49a91a2506000949350505050565b6000610ea283836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506156ed565b6000610ea283836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250615724565b600082613f8e575060006113bb565b82820282848281613f9b57fe5b0414610ea25760405162461bcd60e51b8152600401610c3b90616ac5565b600082820183811015610ea25760405162461bcd60e51b8152600401610c3b90616664565b60008060018381548110613fee57fe5b906000526020600020906004020160030154905060006001808054905003905060016140186125ab565b511161404d5760006001858154811061402d57fe5b9060005260206000209060040201600301819055506000925050506113bb565b846001600160a01b03167f3b6f9ef90462b512a1293ecec018670bf7b7f1876fb727590a8a6d7643130a70836040516140869190616ef0565b60405180910390a26001600160a01b038516600090815260046020526040812055835b6001546000190181101561427357600181600101815481106140c757fe5b9060005260206000209060040201600182815481106140e257fe5b60009182526020909120825460049092020180546001600160a01b03199081166001600160a01b0393841617825560018085015481840180548416918616919091179055600280860180549185018054909416919095161780835584546001600160401b03600160a01b91829004160267ffffffffffffffff60a01b1990911617808355935460ff600160e01b918290041615150260ff60e01b19909416939093179055600392830154920191909155600b8054909183019081106141a357fe5b9060005260206000209060160201600b82815481106141be57fe5b600091825260209091208254601690920201908155600180830154818301805460ff909216151560ff1990921691909117905560028084018054614215938386019390821615610100026000190190911604615eba565b5061422860038281019084016013615f2f565b5090505080600101600460006001848154811061424157fe5b600091825260208083206004909202909101546001600160a01b031683528201929092526040019020556001016140a9565b50600180548061427f57fe5b60008281526020812060046000199093019283020180546001600160a01b0319908116825560018201805490911690556002810180546001600160e81b0319169055600301559055600b8054806142d257fe5b60008281526020812060166000199093019283020181815560018101805460ff19169055906143046002830182615f59565b614312600383016000615f9d565b50509055600081838161432157fe5b04905080156143855760015460005b8181101561438257826001828154811061434657fe5b906000526020600020906004020160030154016001828154811061436657fe5b6000918252602090912060036004909202010155600101614330565b50505b50600195945050505050565b6001548151604080518281526020808402820101909152606092919083908280156143d057816020015b60608152602001906001900390816143bb5790505b50600b5490915083146143e757925061130b915050565b60005b828110156144f657600b60016004600089858151811061440657fe5b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002054038154811061443a57fe5b600091825260209182902060026016909202018101805460408051601f6000196101006001861615020190931694909404918201859004850284018501905280835291929091908301828280156144d25780601f106144a7576101008083540402835291602001916144d2565b820191906000526020600020905b8154815290600101906020018083116144b557829003601f168201915b50505050508282815181106144e357fe5b60209081029190910101526001016143ea565b50949350505050565b60005b8281101561464c57600082878388016040516020016145229291906162e9565b6040516020818303038152906040528051906020012060001c8161454257fe5b06905080850182870114614643576000898388018151811061456057fe5b602002602001015190506060898489018151811061457a57fe5b602002602001015190508a8388018151811061459257fe5b60200260200101518b858a01815181106145a857fe5b60200260200101906001600160a01b031690816001600160a01b031681525050818b848901815181106145d757fe5b60200260200101906001600160a01b031690816001600160a01b031681525050898388018151811061460557fe5b60200260200101518a858a018151811061461b57fe5b6020026020010181905250808a8489018151811061463557fe5b602002602001018190525050505b50600101614502565b5050505050505050565b600980546001908101909155600b80548390811061467057fe5b906000526020600020906016020160010160006101000a81548160ff02191690831515021790555043600b82815481106146a657fe5b600091825260208220601690910201919091556040516001600160a01b038416917ff62981a567ec3cec866c6fa93c55bcdf841d6292d18b8d522ececa769375d82d91a25050565b60008160405160200161470191906162cd565b604051602081830303815290604052805190602001208360405160200161472891906162cd565b6040516020818303038152906040528051906020012014905092915050565b015190565b6001600160a01b038116600090815260046020526040812054806147755750600019905061130b565b60018103905060006001828154811061478a57fe5b90600052602060002090600402016003015490506000600183815481106147ad57fe5b6000918252602090912060036004909202010155600154604051600019909101906001600160a01b038616907f8cd4e147d8af98a9e3b6724021b8bf6aed2e5dac71c38f2dce8161b82585b25d90614806908590616ef0565b60405180910390a28061481e5782935050505061130b565b600081838161482957fe5b04905080156148e55760005b8481101561488757816001828154811061484b57fe5b906000526020600020906004020160030154016001828154811061486b57fe5b6000918252602090912060036004909202010155600101614835565b50600180549085015b818110156148e25782600182815481106148a657fe5b90600052602060002090600402016003015401600182815481106148c657fe5b6000918252602090912060036004909202010155600101614890565b50505b5091949350505050565b6148f7615fac565b506040805180820190915281518152602082810190820152919050565b61491c615e65565b61492582615750565b61492e57600080fd5b600061493d836020015161578a565b60208085015160408051808201909152868152920190820152915050919050565b6000614968615fac565b505080518051602091820151919092015191011190565b614987615fac565b6149908261495e565b61499957600080fd5b602082015160006149a9826157ed565b80830160209586015260408051808201909152908152938401919091525090919050565b8051600090158015906149e257508151602110155b6149eb57600080fd5b60006149fa836020015161578a565b90508083600001511015614a205760405162461bcd60e51b8152600401610c3b90616c83565b8251602080850151830180519284900392918310156144f657506020919091036101000a90049392505050565b6060614a5882615750565b614a6157600080fd5b6000614a6c836158ce565b9050606081604051908082528060200260200182016040528015614aaa57816020015b614a97615fac565b815260200190600190039081614a8f5790505b5090506000614abc856020015161578a565b60208601510190506000805b84811015614b1357614ad9836157ed565b9150604051806040016040528083815260200184815250848281518110614afc57fe5b602090810291909101015291810191600101614ac8565b509195945050505050565b614b26615e85565b60606000614b32615e85565b6060614b3c615e65565b614b4587614914565b90506000805b614b548361495e565b15614c295780614b7f57614b6f614b6a8461497f565b61592a565b6001600160a01b03168552614c21565b8060011415614ba757614b94614b6a8461497f565b6001600160a01b03166020860152614c21565b8060021415614bcf57614bbc614b6a8461497f565b6001600160a01b03166040860152614c21565b8060031415614bfb57614be4612f638461497f565b6001600160401b0316606086015260019150614c21565b8060041415614c1c57614c15614c108461497f565b615944565b9350614c21565b614c29565b600101614b4b565b50929791965091945092505050565b60606113bb614c46836159b4565b615a9a565b6060815160001415614c6c575060408051600081526020810190915261130b565b606082600081518110614c7b57fe5b602002602001015190506000600190505b8351811015614cbc57614cb282858381518110614ca557fe5b6020026020010151615aec565b9150600101614c8c565b50610ea2614ccf825160c060ff16615b69565b82615aec565b606080600080808080614ce66126a7565b6001549091505b8015614df457600181039250600b8381548110614d0657fe5b600091825260209091206001601690920201015460ff16614d2657614deb565b60018381548110614d3357fe5b60009182526020909120600490910201546001600160a01b03169450614d5a858484612d27565b9350831580614d6d575060018a51038610155b15614d7757614deb565b60005b8a51811015614de957856001600160a01b03168b8281518110614d9957fe5b6020026020010151600001516001600160a01b03161415614de15760018b8281518110614dc257fe5b6020908102919091010151901515608090910152600190960195614de9565b600101614d7a565b505b60001901614ced565b5084895103604051908082528060200260200182016040528015614e3257816020015b614e1f615e85565b815260200190600190039081614e175790505b50965084895103604051908082528060200260200182016040528015614e6c57816020015b6060815260200190600190039081614e575790505b5095506000915060005b8951811015614f0057898181518110614e8b57fe5b602002602001015160800151614ef857898181518110614ea757fe5b6020026020010151888481518110614ebb57fe5b6020026020010181905250888181518110614ed257fe5b6020026020010151878481518110614ee657fe5b60200260200101819052508260010192505b600101614e76565b5050505050505b9250929050565b600154825160005b8281101561502b576001614f28615e85565b60018381548110614f3557fe5b600091825260208083206040805160c08101825260049490940290910180546001600160a01b0390811685526001820154811693850193909352600281015492831691840191909152600160a01b82046001600160401b03166060840152600160e01b90910460ff16151560808301526003015460a082015291505b84811015614fff57878181518110614fc557fe5b6020026020010151600001516001600160a01b031682600001516001600160a01b03161415614ff75760009250614fff565b600101614fb1565b5081156150215780516001600160a01b03166000908152600460205260408120555b5050600101614f16565b50808211156150ea57805b828110156150e857600180548061504957fe5b60008281526020812060046000199093019283020180546001600160a01b0319908116825560018201805490911690556002810180546001600160e81b0319169055600301559055600b80548061509c57fe5b60008281526020812060166000199093019283020181815560018101805460ff19169055906150ce6002830182615f59565b6150dc600383016000615f9d565b50509055600101615036565b505b60008183106150f957816150fb565b825b905060005b8181101561549f576151ad86828151811061511757fe5b60200260200101516001838154811061512c57fe5b60009182526020918290206040805160c08101825260049390930290910180546001600160a01b0390811684526001820154811694840194909452600281015493841691830191909152600160a01b83046001600160401b03166060830152600160e01b90920460ff161515608082015260039091015460a0820152615c3b565b6153615780600101600460008884815181106151c557fe5b6020026020010151600001516001600160a01b03166001600160a01b031681526020019081526020016000208190555085818151811061520157fe5b60200260200101516001828154811061521657fe5b6000918252602091829020835160049092020180546001600160a01b039283166001600160a01b0319918216178255928401516001820180549184169185169190911790556040840151600282018054606087015160808801511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b1995909716929097169190911792909216939093171692909217905560a09091015160039091015584518590829081106152d157fe5b6020026020010151600b82815481106152e657fe5b9060005260206000209060160201600201908051906020019061530a929190615d9a565b506000600b828154811061531a57fe5b60009182526020822060169190910201600101805460ff191692151592909217909155600b80548390811061534b57fe5b6000918252602090912060169091020155615497565b61542785828151811061537057fe5b6020026020010151600b838154811061538557fe5b600091825260209182902060026016909202018101805460408051601f60001961010060018616150201909316949094049182018590048502840185019052808352919290919083018282801561541d5780601f106153f25761010080835404028352916020019161541d565b820191906000526020600020905b81548152906001019060200180831161540057829003601f168201915b5050505050615cbc565b6154725784818151811061543757fe5b6020026020010151600b828154811061544c57fe5b90600052602060002090601602016002019080519060200190615470929190615d9a565b505b60006001828154811061548157fe5b9060005260206000209060040201600301819055505b600101615100565b5082821115615677576154b0615d6b565b835b83811015615674578581815181106154c657fe5b6020026020010151826040018190525060018782815181106154e457fe5b6020908102919091018101518254600181810185556000948552838520835160049093020180546001600160a01b039384166001600160a01b0319918216178255848601518284018054918616918316919091179055604080860151600284018054606089015160808a01511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b1995909a1692909616919091179290921696909617169190911790935560a090930151600390930192909255600b805492830181559093528451601690910260008051602061714e83398151915281019182558583015160008051602061718e8339815191528201805491151560ff199092169190911790559285015180518694929361561a9360008051602061716e83398151915201920190615d9a565b5060608201516156309060038301906013615e14565b505050806001016004600089848151811061564757fe5b602090810291909101810151516001600160a01b03168252810191909152604001600020556001016154b2565b50505b6000600981905560015493505b838110156156e5576000600b828154811061569b57fe5b60009182526020822060169190910201600101805460ff191692151592909217909155600b8054839081106156cc57fe5b6000918252602090912060169091020155600101615684565b505050505050565b6000818361570e5760405162461bcd60e51b8152600401610c3b919061646e565b50600083858161571a57fe5b0495945050505050565b600081848411156157485760405162461bcd60e51b8152600401610c3b919061646e565b505050900390565b80516000906157615750600061130b565b6020820151805160001a9060c08210156157805760009250505061130b565b5060019392505050565b8051600090811a60808110156157a457600091505061130b565b60b88110806157bf575060c081108015906157bf575060f881105b156157ce57600191505061130b565b60c08110156157e25760b51901905061130b565b60f51901905061130b565b80516000908190811a608081101561580857600191506158c7565b60b881101561581d57607e19810191506158c7565b60c081101561586e57600060b78203600186019550806020036101000a8651049150600181018201935050808310156158685760405162461bcd60e51b8152600401610c3b90616a12565b506158c7565b60f88110156158835760be19810191506158c7565b600060f78203600186019550806020036101000a8651049150600181018201935050808310156158c55760405162461bcd60e51b8152600401610c3b90616a12565b505b5092915050565b80516000906158df5750600061130b565b600080905060006158f3846020015161578a565b602085015185519181019250015b8082101561592157615912826157ed565b82019150826001019250615901565b50909392505050565b805160009060151461593b57600080fd5b6113bb826149cd565b805160609061595257600080fd5b6000615961836020015161578a565b83516040805191839003808352601f19601f8201168301602001909152919250606090828015615998576020820181803683370190505b50905060008160200190506144f6848760200151018285615d20565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff1984166159f857506018615a1c565b6fffffffffffffffffffffffffffffffff198416615a1857506010615a1c565b5060005b6020811015615a5257818181518110615a3157fe5b01602001516001600160f81b03191615615a4a57615a52565b600101615a1c565b60008160200390506060816040519080825280601f01601f191660200182016040528015615a87576020820181803683370190505b5080830196909652508452509192915050565b606081516001148015615acc5750607f60f81b82600081518110615aba57fe5b01602001516001600160f81b03191611155b15615ad857508061130b565b6113bb615aea8351608060ff16615b69565b835b6060806040519050835180825260208201818101602087015b81831015615b1d578051835260209283019201615b05565b50855184518101855292509050808201602086015b81831015615b4a578051835260209283019201615b32565b508651929092011591909101601f01601f191660405250905092915050565b6060680100000000000000008310615b935760405162461bcd60e51b8152600401610c3b90616816565b60408051600180825281830190925260609160208201818036833701905050905060378411615bed5782840160f81b81600081518110615bcf57fe5b60200101906001600160f81b031916908160001a90535090506113bb565b6060615bf8856159b4565b90508381510160370160f81b82600081518110615c1157fe5b60200101906001600160f81b031916908160001a905350615c328282615aec565b95945050505050565b805182516000916001600160a01b039182169116148015615c75575081602001516001600160a01b031683602001516001600160a01b0316145b8015615c9a575081604001516001600160a01b031683604001516001600160a01b0316145b8015610ea25750506060908101519101516001600160401b0390811691161490565b815181516000916001918114808314615cd85760009250615d16565b600160208701838101602088015b600284838510011415615d11578051835114615d055760009650600093505b60209283019201615ce6565b505050505b5090949350505050565b80615d2a57610c5b565b5b60208110615d4a578251825260209283019290910190601f1901615d2b565b915181516020939093036101000a6000190180199091169216919091179052565b60405180608001604052806000815260200160001515815260200160608152602001615d95615fc6565b905290565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10615ddb57805160ff1916838001178555615e08565b82800160010185558215615e08579182015b82811115615e08578251825591602001919060010190615ded565b506126e2929150615fe5565b8260138101928215615e085791602002820182811115615e08578251825591602001919060010190615ded565b6040518060600160405280600060ff16815260200160608152602001606081525090565b6040518060400160405280615e78615fac565b8152602001600081525090565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a081019190915290565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10615ef35780548555615e08565b82800160010185558215615e0857600052602060002091601f016020900482015b82811115615e08578254825591600101919060010190615f14565b8260138101928215615e085791820182811115615e08578254825591600101919060010190615f14565b50805460018160011615610100020316600290046000825580601f10615f7f5750611517565b601f0160209004906000526020600020908101906115179190615fe5565b50611517906013810190615fe5565b604051806040016040528060008152602001600081525090565b6040518061026001604052806013906020820280368337509192915050565b61269491905b808211156126e25760008155600101615feb565b60008083601f840112616010578182fd5b5081356001600160401b03811115616026578182fd5b6020830191508360208083028501011115614f0757600080fd5b60008083601f840112616051578182fd5b5081356001600160401b03811115616067578182fd5b602083019150836020828501011115614f0757600080fd5b600060208284031215616090578081fd5b81356001600160a01b0381168114610ea2578182fd5b600080600080604085870312156160bb578283fd5b84356001600160401b03808211156160d1578485fd5b6160dd88838901615fff565b909650945060208701359150808211156160f5578384fd5b5061610287828801615fff565b95989497509550505050565b60006020828403121561611f578081fd5b81518015158114610ea2578182fd5b60008060008060408587031215616143578384fd5b84356001600160401b0380821115616159578586fd5b61616588838901616040565b9096509450602087013591508082111561617d578384fd5b5061610287828801616040565b60006020828403121561619b578081fd5b5035919050565b6000602082840312156161b3578081fd5b5051919050565b600080604083850312156161cc578182fd5b505080516020909101519092909150565b6000806000604084860312156161f1578283fd5b833560ff81168114616201578384fd5b925060208401356001600160401b0381111561621b578283fd5b61622786828701616040565b9497909650939450505050565b6000815180845260208085019450808401835b8381101561626c5781516001600160a01b031687529582019590820190600101616247565b509495945050505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b600081518084526162b9816020860160208601616f56565b601f01601f19169290920160200192915050565b600082516162df818460208701616f56565b9190910192915050565b918252602082015260400190565b6001600160a01b0391909116815260200190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b03968716815294861660208601529290941660408401526001600160401b03166060830152911515608082015260a081019190915260c00190565b600060208252610ea26020830184616234565b60006040825261638c6040830185616234565b602083820381850152818551808452828401915082838202850101838801865b838110156163da57601f198784030185526163c88383516162a1565b948601949250908501906001016163ac565b50909998505050505050505050565b6000608082526163fc6080830187616234565b828103602084810191909152865180835287820192820190845b8181101561643257845183529383019391830191600101616416565b505084810360408601526164468188616234565b93505050506001600160401b038316606083015295945050505050565b901515815260200190565b600060208252610ea260208301846162a1565b600060408252616495604083018688616277565b82810360208401526164a8818587616277565b979650505050505050565b6020808252601c908201527f6c656e677468206f66206275726e526174696f206d69736d6174636800000000604082015260600190565b60208082526026908201527f6c656e677468206f66206d61784e756d4f664d61696e7461696e696e67206d696040820152650e6dac2e8c6d60d31b606082015260800190565b6020808252601b908201527f6261746368207472616e736665722072657475726e2066616c73650000000000604082015260600190565b6020808252602c908201527f6c656e677468206f66206d61784e756d4f66576f726b696e6743616e6469646160408201526b0e8cae640dad2e6dac2e8c6d60a31b606082015260800190565b60208082526025908201527f6c656e677468206f66206d61696e7461696e536c6173685363616c65206d69736040820152640dac2e8c6d60db1b606082015260800190565b6020808252818101527f6c656e677468206f66206e756d4f66436162696e657473206d69736d61746368604082015260600190565b60208082526019908201527f74686520636f6e7472616374206e6f7420696e69742079657400000000000000604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b60208082526028908201527f746865206e756d4f66436162696e657473206d75737420626520677265617465604082015267072207468616e20360c41b606082015260800190565b60208082526039908201527f746865206e756d4f66436162696e657473206d757374206265206c657373207460408201527f68616e204d41585f4e554d5f4f465f56414c494441544f525300000000000000606082015260800190565b60208082526029908201527f746865206e756d626572206f662076616c696461746f727320657863656564206040820152681d1a19481b1a5b5a5d60ba1b606082015260800190565b60208082526022908201527f63616e206e6f7420646f207468697320747769636520696e206f6e6520626c6f604082015261636b60f01b606082015260800190565b6020808252602b908201527f746865206275726e526174696f206d757374206265206e6f206772656174657260408201526a0207468616e2031303030360ac1b606082015260800190565b6020808252600e908201526d696e70757420746f6f206c6f6e6760901b604082015260600190565b60208082526037908201527f746865206d61784e756d4f664d61696e7461696e696e67206d7573742062652060408201527f6c657373207468616e206e756d4f66436162696e657473000000000000000000606082015260800190565b6020808252602b908201527f6475706c696361746520636f6e73656e7375732061646472657373206f66207660408201526a185b1a59185d1bdc94d95d60aa1b606082015260800190565b60208082526027908201527f7468652065787069726554696d655365636f6e64476170206973206f7574206f604082015266662072616e676560c81b606082015260800190565b6020808252601590820152746465706f7369742076616c7565206973207a65726f60581b604082015260600190565b60208082526049908201527f746865206d61784e756d4f66576f726b696e6743616e64696461746573206d7560408201527f7374206265206e6f742067726561746572207468616e206d61784e756d4f6643606082015268616e6469646174657360b81b608082015260a00190565b60208082526027908201527f7468652066696e616c697479526577617264526174696f206973206f7574206f604082015266662072616e676560c81b606082015260800190565b6020808252601190820152706164646974696f6e206f766572666c6f7760781b604082015260600190565b60208082526023908201527f63616e206e6f7420656e7465722054656d706f72617279204d61696e74656e616040820152626e636560e81b606082015260800190565b60208082526025908201527f6c656e677468206f66206a61696c2076616c696461746f7273206d757374206260408201526465206f6e6560d81b606082015260800190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252602e908201527f746865206d6573736167652073656e646572206d75737420626520676f76657260408201526d1b985b98d94818dbdb9d1c9858dd60921b606082015260800190565b60208082526025908201527f6c656e677468206f66206d61784e756d4f6643616e64696461746573206d69736040820152640dac2e8c6d60db1b606082015260800190565b6020808252601290820152716e6f7420696e206d61696e74656e616e636560701b604082015260600190565b60208082526021908201527f666565206973206c6172676572207468616e2044555354595f494e434f4d494e6040820152604760f81b606082015260800190565b60208082526019908201527f74686520636f6e747261637420616c726561647920696e697400000000000000604082015260600190565b60208082526026908201527f6c656e677468206f662066696e616c697479526577617264526174696f206d696040820152650e6dac2e8c6d60d31b606082015260800190565b6020808252601a908201527f6c656e677468206973206c657373207468616e206f6666736574000000000000604082015260600190565b60208082526026908201527f6c656e677468206f662065787069726554696d655365636f6e64476170206d696040820152650e6dac2e8c6d60d31b606082015260800190565b60208082526017908201527f6f6e6c792063757272656e742076616c696461746f7273000000000000000000604082015260600190565b60208082526021908201527f6661696c656420746f20706172736520696e69742076616c696461746f7253656040820152601d60fa1b606082015260800190565b6020808252602f908201527f746865206d6573736167652073656e646572206d7573742062652063726f737360408201526e0818da185a5b8818dbdb9d1c9858dd608a1b606082015260800190565b6020808252602d908201527f746865206d6573736167652073656e646572206d75737420626520746865206260408201526c3637b1b590383937b23ab1b2b960991b606082015260800190565b6020808252603e908201527f746865206d61696e7461696e536c6173685363616c65206d757374206265206760408201527f726561746572207468616e203020616e64206c657373207468616e2031300000606082015260800190565b6020808252600d908201526c756e6b6e6f776e20706172616d60981b604082015260600190565b60208082526029908201527f746865206d6573736167652073656e646572206d75737420626520736c6173686040820152680818dbdb9d1c9858dd60ba1b606082015260800190565b61ffff91909116815260200190565b90815260200190565b6000848252831515602083015260606040830152615c3260608301846162a1565b63ffffffff91909116815260200190565b60ff91909116815260200190565b600060ff8516825260406020830152615c32604083018486616277565b60005b83811015616f71578181015183820152602001616f59565b83811115612c47575050600091015256fef901a880f901a4f844941284214b9b9c85549ab3d2b972df0deef66ac2c9946ddf42a51534fc98d0c0a3b42c963cace8441ddf946ddf42a51534fc98d0c0a3b42c963cace8441ddf8410000000f84494a2959d3f95eae5dc7d70144ce1b73b403b7eb6e0948081ef03f1d9e0bb4a5bf38f16285c879299f07f948081ef03f1d9e0bb4a5bf38f16285c879299f07f8410000000f8449435552c16704d214347f29fa77f77da6d75d7c75294dc4973e838e3949c77aced16ac2315dc2d7ab11194dc4973e838e3949c77aced16ac2315dc2d7ab1118410000000f84494980a75ecd1309ea12fa2ed87a8744fbfc9b863d594cc6ac05c95a99c1f7b5f88de0e3486c82293b27094cc6ac05c95a99c1f7b5f88de0e3486c82293b2708410000000f84494f474cf03cceff28abc65c9cbae594f725c80e12d94e61a183325a18a173319dd8e19c8d069459e217594e61a183325a18a173319dd8e19c8d069459e21758410000000f84494b71b214cb885500844365e95cd9942c7276e7fd894d22ca3ba2141d23adab65ce4940eb7665ea2b6a794d22ca3ba2141d23adab65ce4940eb7665ea2b6a7841000000070e72399380dcfb0338abc03dc8d47f9f470ada8e769c9a78d644ea97385ecb20175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db90175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01dbb0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01dbaa2646970667358221220df3b2f2afc524f6a9eb81529e8bd736333e37b7197419580d4e42bd858b6b14264736f6c63430006040033", + }, + { + ContractAddr: common.HexToAddress(SlashContract), + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/b144718e94d7a1ebb24a7103202300f08826f369", + Code: "608060405234801561001057600080fd5b506004361061027f5760003560e01c80637942fd051161015c578063c80d4b8f116100ce578063dc927faf11610087578063dc927faf146104ad578063e1c7392a146104b5578063f9a2bbc7146104bd578063fc3e5908146104c5578063fc4333cd146104cd578063fd6a6879146104d55761027f565b8063c80d4b8f1461045c578063c81b166214610464578063c8509d811461046c578063c96be4cb1461047f578063cc844b7314610492578063d2a42e4b146104a55761027f565b80639dc09262116101205780639dc0926214610421578063a1a11bf514610429578063a78abc1614610431578063ab51bb9614610439578063ac0af62914610441578063ac431751146104495761027f565b80637942fd05146103ee5780638256ace6146103f6578063831d65d1146103fe57806396713da9146104115780639bc8e4f2146104195761027f565b8063493279b1116101f557806362b72cf5116101b957806362b72cf5146103be5780636e47b482146103c657806370fd5bad146103ce578063718a8aa8146103d657806375d47a0a146103de5780637912a65d146103e65761027f565b8063493279b11461037c5780634bf6c8821461039157806351e8067214610399578063567a372d146103a15780635bfb4990146103a95761027f565b806335aa2e441161024757806335aa2e441461030e57806337c8dab914610321578063389f4f71146103425780633a63f4b1146103575780633dffc3871461035f57806343756e5c146103745761027f565b80630bee7a67146102845780630e2374a5146102a25780631182b875146102b757806322d1e80b146102d757806323bac5a2146102ec575b600080fd5b61028c6104dd565b60405161029991906132a4565b60405180910390f35b6102aa6104e2565b6040516102999190612b82565b6102ca6102c5366004612ab8565b6104e8565b6040516102999190612bba565b6102df61054e565b6040516102999190612baf565b6102ff6102fa366004612866565b610557565b6040516102999392919061328c565b6102aa61031c366004612a88565b61057a565b61033461032f366004612866565b6105a1565b60405161029992919061327e565b61034a6105f8565b6040516102999190613254565b61034a6105fe565b610367610604565b60405161029991906132b5565b6102aa610609565b61038461060f565b6040516102999190613245565b610367610614565b6102aa610619565b61034a61061f565b6103bc6103b7366004612866565b610625565b005b61034a6106d0565b6102aa6106d6565b6103676106dc565b6103676106e1565b6102aa6106e6565b61034a6106ec565b6103676106f1565b6103346106f6565b6103bc61040c366004612ab8565b610700565b610367610812565b61034a610817565b6102aa610822565b6102aa610828565b6102df61082e565b61028c610837565b61034a61083c565b6103bc61045736600461296c565b610841565b61034a610ce0565b6102aa610ce5565b6103bc61047a366004612ab8565b610ceb565b6103bc61048d366004612866565b610d5c565b6103bc6104a03660046129d5565b61114d565b61034a61169a565b6102aa61169f565b6103bc6116a5565b6102aa6116e1565b6103676116e7565b6103bc6116ec565b6102aa611b35565b606481565b61200181565b606033612000146105145760405162461bcd60e51b815260040161050b906130cb565b60405180910390fd5b60005460ff166105365760405162461bcd60e51b815260040161050b90612c9b565b60405162461bcd60e51b815260040161050b9061318e565b60075460ff1681565b600260208190526000918252604090912080546001820154919092015460ff1683565b6001818154811061058757fe5b6000918252602090912001546001600160a01b0316905081565b6000806105ac61264d565b5050506001600160a01b0316600090815260026020818152604092839020835160608101855281548082526001830154938201849052919093015460ff16151592909301919091529091565b60055481565b60065481565b600181565b61100181565b606181565b600881565b61200081565b60045481565b33611000146106465760405162461bcd60e51b815260040161050b90612edf565b60005460ff166106685760405162461bcd60e51b815260040161050b90612c9b565b61200063f7a251d7600b61067b84611b3b565b60006040518463ffffffff1660e01b815260040161069b939291906132c3565b600060405180830381600087803b1580156106b557600080fd5b505af11580156106c9573d6000803e3d6000fd5b5050505050565b60035481565b61100581565b600281565b601081565b61100881565b603281565b600b81565b6004546005549091565b33612000146107215760405162461bcd60e51b815260040161050b906130cb565b60005460ff166107435760405162461bcd60e51b815260040161050b90612c9b565b61074b612670565b600061078c84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611c0d92505050565b9150915080156107d35781516040517f7f0956d47419b9525356e7111652b653b530ec6f5096dccc04589bc38e629967916107c6916132a4565b60405180910390a16106c9565b81516040517f7d45f62d17443dd4547bca8a8112c60e2385669318dc300ec61a5d2492f262e791610803916132a4565b60405180910390a15050505050565b600981565b662386f26fc1000081565b61100781565b61100681565b60005460ff1681565b600081565b600481565b60005460ff166108635760405162461bcd60e51b815260040161050b90612c9b565b33611007146108845760405162461bcd60e51b815260040161050b90612f88565b6108ef84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260148152731b5a5cd9195b59585b9bdc951a1c995cda1bdb1960621b60208201529150611c8d9050565b1561098a57602081146109145760405162461bcd60e51b815260040161050b90612e6b565b604080516020601f840181900481028201810190925282815260009161095291858580838501838280828437600092019190915250611ce792505050565b905060018110158015610966575060055481105b6109825760405162461bcd60e51b815260040161050b90613086565b600455610c9d565b6109f084848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600f81526e19995b1bdb9e551a1c995cda1bdb19608a1b60208201529150611c8d9050565b15610a8c5760208114610a155760405162461bcd60e51b815260040161050b90612fd6565b604080516020601f8401819004810282018101909252828152600091610a5391858580838501838280828437600092019190915250611ce792505050565b90506103e88111158015610a68575060045481115b610a845760405162461bcd60e51b815260040161050b90612d09565b600555610c9d565b610b0084848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601881527f66696e616c697479536c617368526577617264526174696f000000000000000060208201529150611c8d9050565b15610b9a5760208114610b255760405162461bcd60e51b815260040161050b906131c5565b604080516020601f8401819004810282018101909252828152600091610b6391858580838501838280828437600092019190915250611ce792505050565b9050600a8110158015610b765750606481105b610b925760405162461bcd60e51b815260040161050b90612e1f565b600655610c9d565b610c0e84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601881527f656e61626c654d616c6963696f7573566f7465536c617368000000000000000060208201529150611c8d9050565b15610c855760208114610c335760405162461bcd60e51b815260040161050b90612d3e565b604080516020601f8401819004810282018101909252828152610c6f9190848480838501838280828437600092019190915250611cec92505050565b6007805460ff1916911515919091179055610c9d565b60405162461bcd60e51b815260040161050b90613167565b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a84848484604051610cd29493929190612bcd565b60405180910390a150505050565b609681565b61100281565b3361200014610d0c5760405162461bcd60e51b815260040161050b906130cb565b60005460ff16610d2e5760405162461bcd60e51b815260040161050b90612c9b565b6040517f07db600eebe2ac176be8dcebad61858c245a4961bb32ca2aa3d159b09aa0810e90600090a1505050565b334114610d7b5760405162461bcd60e51b815260040161050b9061311a565b60005460ff16610d9d5760405162461bcd60e51b815260040161050b90612c9b565b6003544311610dbe5760405162461bcd60e51b815260040161050b90613210565b3a15610ddc5760405162461bcd60e51b815260040161050b90612f5a565b60405163155853f360e21b8152611000906355614fcc90610e01908490600401612b82565b60206040518083038186803b158015610e1957600080fd5b505afa158015610e2d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e51919061294c565b610e5a57611146565b610e6261264d565b506001600160a01b0381166000908152600260208181526040928390208351606081018552815481526001820154928101929092529091015460ff161580159282019290925290610ebd576020810180516001019052610f16565b60016040820181905260208201819052805480820182556000919091527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf60180546001600160a01b0319166001600160a01b0384161790555b438152600554602082015181610f2857fe5b0661107457600060208201526040516335409f7f60e01b8152611000906335409f7f90610f59908590600401612b82565b600060405180830381600087803b158015610f7357600080fd5b505af1158015610f87573d6000803e3d6000fd5b505050506120006001600160a01b031663f7a251d7600b610fa785611b3b565b60006040518463ffffffff1660e01b8152600401610fc7939291906132c3565b600060405180830381600087803b158015610fe157600080fd5b505af1925050508015610ff2575060015b61106f573d808015611020576040519150601f19603f3d011682016040523d82523d6000602084013e611025565b606091505b50826001600160a01b03167fd7bc86ff5d08c8ab043edec743302aba2520e6635172a428bc956721db9e2d1c83602001518360405161106592919061325d565b60405180910390a2505b6110e0565b60045481602001518161108357fe5b066110e0576040516375abf10160e11b81526110009063eb57e202906110ad908590600401612b82565b600060405180830381600087803b1580156110c757600080fd5b505af11580156110db573d6000803e3d6000fd5b505050505b6001600160a01b0382166000818152600260208181526040808420865181559186015160018301558581015191909201805460ff1916911515919091179055517fddb6012116e51abf5436d956a4f0ebd927e92c576ff96d7918290c8782291e3e9190a2505b5043600355565b60005460ff1661116f5760405162461bcd60e51b815260040161050b90612c9b565b604051630a83aaa960e31b81526110069063541d554890611194903390600401612b82565b60206040518083038186803b1580156111ac57600080fd5b505afa1580156111c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111e4919061294c565b6112005760405162461bcd60e51b815260040161050b90612bff565b60075460ff166112225760405162461bcd60e51b815260040161050b90612c66565b60065461122f5760146006555b8051514361010090910111801561125157504381602001516000015161010001115b61126d5760405162461bcd60e51b815260040161050b90612c36565b80602001516020015181600001516020015114801561129b5750806020015160600151816000015160600151145b156112b85760405162461bcd60e51b815260040161050b90612eb2565b8051604081015190511080156112d75750602081015160408101519051105b6112f35760405162461bcd60e51b815260040161050b90612de8565b6020810151518151511080156113185750806000015160400151816020015160400151105b8061134357508051516020820151511080156113435750806020015160400151816000015160400151105b8061135d5750806020015160400151816000015160400151145b6113795760405162461bcd60e51b815260040161050b90612cd2565b61138b81600001518260400151611d14565b80156113a457506113a481602001518260400151611d14565b6113c05760405162461bcd60e51b815260040161050b90612d89565b6060806110006001600160a01b0316633b071dcc6040518163ffffffff1660e01b815260040160006040518083038186803b1580156113fe57600080fd5b505afa158015611412573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261143a9190810190612889565b9150915060005b81518110156115775761146b82828151811061145957fe5b60200260200101518560400151611eec565b1561156f576006546040516309a99b4f60e41b815260646110028031909302049190639a99b4f0906114a39033908590600401612b96565b602060405180830381600087803b1580156114bd57600080fd5b505af11580156114d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114f59190612aa0565b506110006001600160a01b03166335409f7f85848151811061151357fe5b60200260200101516040518263ffffffff1660e01b81526004016115379190612b82565b600060405180830381600087803b15801561155157600080fd5b505af1158015611565573d6000803e3d6000fd5b5050505050611577565b600101611441565b50600061158984604001516000611f50565b90506120006001600160a01b031663f7a251d7600b6115ab8760400151611f6c565b60006040518463ffffffff1660e01b81526004016115cb939291906132c3565b600060405180830381600087803b1580156115e557600080fd5b505af19250505080156115f6575060015b611668573d808015611624576040519150601f19603f3d011682016040523d82523d6000602084013e611629565b606091505b50817fd58d1183100bd0932c0588f31c4205d6bc6168909765a96c41adbed3115f36288260405161165a9190612bba565b60405180910390a250611694565b60405181907f7b78aadacff901d8b63d0dba4f86283d4db8aef27f9ed70413dd860f1c9532b690600090a25b50505050565b601481565b61100381565b60005460ff16156116c85760405162461bcd60e51b815260040161050b90613018565b603260045560966005556000805460ff19166001179055565b61100081565b600381565b336110001461170d5760405162461bcd60e51b815260040161050b90612edf565b60005460ff1661172f5760405162461bcd60e51b815260040161050b90612c9b565b60015461173b57611b33565b600154600090600019015b808211611b07576000805b8284101561186a5761176161264d565b600260006001878154811061177257fe5b60009182526020808320909101546001600160a01b0316835282810193909352604091820190208151606081018352815481526001820154938101939093526002015460ff161515908201526005549091506004900481602001511115611854576004600554816117df57fe5b0481602001510381602001818152505080600260006001888154811061180157fe5b6000918252602080832091909101546001600160a01b0316835282810193909352604091820190208351815591830151600183015591909101516002909101805460ff191691151591909117905561185e565b600192505061186a565b50836001019350611751565b828411611a015761187961264d565b600260006001868154811061188a57fe5b60009182526020808320909101546001600160a01b0316835282810193909352604091820190208151606081018352815481526001820154938101939093526002015460ff161515908201526005549091506004900481602001511115611972576004600554816118f757fe5b0481602001510381602001818152505080600260006001878154811061191957fe5b6000918252602080832091909101546001600160a01b03168352828101939093526040918201902083518155918301516001808401919091559201516002909101805460ff19169115159190911790559150611a019050565b600260006001868154811061198357fe5b60009182526020808320909101546001600160a01b031683528201929092526040018120818155600181810192909255600201805460ff191690558054806119c757fe5b600082815260209020810160001990810180546001600160a01b0319169055019055836119f45750611a01565b506000199092019161186a565b818015611a0b5750805b15611aea576002600060018681548110611a2157fe5b60009182526020808320909101546001600160a01b031683528201929092526040018120818155600181810192909255600201805460ff19169055805484908110611a6857fe5b600091825260209091200154600180546001600160a01b039092169186908110611a8e57fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506001805480611ac757fe5b600082815260209020810160001990810180546001600160a01b03191690550190555b82611af6575050611b07565b505060019091019060001901611746565b6040517fcfdb3b6ccaeccbdc68be3c59c840e3b3c90f0a7c491f5fff1cf56cfda200dd9c90600090a150505b565b61100481565b60408051600480825260a08201909252606091829190816020015b6060815260200190600190039081611b56579050509050611b7f836001600160a01b0316611fa7565b81600081518110611b8c57fe5b6020026020010181905250611ba043611fca565b81600181518110611bad57fe5b6020908102919091010152611bc26061611fca565b81600281518110611bcf57fe5b6020026020010181905250611be342611fca565b81600381518110611bf057fe5b6020026020010181905250611c0481611fdd565b9150505b919050565b611c15612670565b6000611c1f612670565b611c27612682565b611c38611c3386612067565b61208c565b90506000805b611c47836120d6565b15611c805780611c7357611c62611c5d846120f7565b612145565b63ffffffff16845260019150611c78565b611c80565b600101611c3e565b5091935090915050915091565b600081604051602001611ca09190612b66565b6040516020818303038152906040528051906020012083604051602001611cc79190612b66565b604051602081830303815290604052805190602001201490505b92915050565b015190565b8082015160009060ff811615611d06576001915081611d0c565b60009150815b505092915050565b60408051600480825260a0820190925260009160609190816020015b6060815260200190600190039081611d30575050604080516020808252818301909252919250606091908082018180368337019050509050611d758560000151611fca565b82600081518110611d8257fe5b6020026020010181905250611d9d60208660200151836121c7565b611da6816121d7565b82600181518110611db357fe5b6020026020010181905250611dcb8560400151611fca565b82600281518110611dd857fe5b6020026020010181905250611df360208660600151836121c7565b611dfc816121d7565b82600381518110611e0957fe5b6020026020010181905250611e2f6020611e2284611fdd565b80519060200120836121c7565b6040805160b080825260e08201909252606091602082018180368337019050509050611e5f81836000602061222d565b611e718187608001516020606061222d565b611e7f81866080603061222d565b604080516001808252818301909252606091602082018180368337019050509050815160016020830182602086016066600019fa611ebc57600080fd5b506001611eca826000612280565b60ff1614611edf576000945050505050611ce1565b5060019695505050505050565b815181516000916001918114808314611f085760009250611f46565b600160208701838101602088015b600284838510011415611f41578051835114611f355760009650600093505b60209283019201611f16565b505050505b5090949350505050565b60008160200183511015611f6357600080fd5b50016020015190565b60408051600480825260a08201909252606091829190816020015b6060815260200190600190039081611f87579050509050611b7f836121d7565b60408051600560a21b8318601482015260348101909152606090611c04816121d7565b6060611ce1611fd88361229c565b6121d7565b6060815160001415611ffe5750604080516000815260208101909152611c08565b60608260008151811061200d57fe5b602002602001015190506000600190505b835181101561204e576120448285838151811061203757fe5b6020026020010151612382565b915060010161201e565b50611c04612061825160c060ff166123ff565b82612382565b61206f6126a2565b506040805180820190915281518152602082810190820152919050565b612094612682565b61209d826124d1565b6120a657600080fd5b60006120b5836020015161250b565b60208085015160408051808201909152868152920190820152915050919050565b60006120e06126a2565b505080518051602091820151919092015191011190565b6120ff6126a2565b612108826120d6565b61211157600080fd5b602082015160006121218261256e565b80830160209586015260408051808201909152908152938401919091525090919050565b80516000901580159061215a57508151602110155b61216357600080fd5b6000612172836020015161250b565b905080836000015110156121985760405162461bcd60e51b815260040161050b9061304f565b8251602080850151830180519284900392918310156121be57826020036101000a820491505b50949350505050565b9091018181526020918201910152565b6060815160011480156122095750607f60f81b826000815181106121f757fe5b01602001516001600160f81b03191611155b15612215575080611c08565b611ce16122278351608060ff166123ff565b83612382565b60005b818110156106c95783818151811061224457fe5b602001015160f81c60f81b85848060010195508151811061226157fe5b60200101906001600160f81b031916908160001a905350600101612230565b6000816001018351101561229357600080fd5b50016001015190565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff1984166122e057506018612304565b6fffffffffffffffffffffffffffffffff19841661230057506010612304565b5060005b602081101561233a5781818151811061231957fe5b01602001516001600160f81b031916156123325761233a565b600101612304565b60008160200390506060816040519080825280601f01601f19166020018201604052801561236f576020820181803683370190505b5080830196909652508452509192915050565b6060806040519050835180825260208201818101602087015b818310156123b357805183526020928301920161239b565b50855184518101855292509050808201602086015b818310156123e05780518352602092830192016123c8565b508651929092011591909101601f01601f191660405250905092915050565b60606801000000000000000083106124295760405162461bcd60e51b815260040161050b90612dc0565b604080516001808252818301909252606091602082018180368337019050509050603784116124835782840160f81b8160008151811061246557fe5b60200101906001600160f81b031916908160001a9053509050611ce1565b606061248e8561229c565b90508381510160370160f81b826000815181106124a757fe5b60200101906001600160f81b031916908160001a9053506124c88282612382565b95945050505050565b80516000906124e257506000611c08565b6020820151805160001a9060c082101561250157600092505050611c08565b5060019392505050565b8051600090811a6080811015612525576000915050611c08565b60b8811080612540575060c08110801590612540575060f881105b1561254f576001915050611c08565b60c08110156125635760b519019050611c08565b60f519019050611c08565b80516000908190811a60808110156125895760019150612646565b60b881101561259e57607e1981019150612646565b60c08110156125ef57600060b78203600186019550806020036101000a8651049150600181018201935050808310156125e95760405162461bcd60e51b815260040161050b90612f2f565b50612646565b60f88110156126045760be1981019150612646565b600060f78203600186019550806020036101000a865104915060018101820193505080831015611d0c5760405162461bcd60e51b815260040161050b90612f2f565b5092915050565b604051806060016040528060008152602001600081526020016000151581525090565b60408051602081019091526000815290565b60405180604001604052806126956126a2565b8152602001600081525090565b604051806040016040528060008152602001600081525090565b600082601f8301126126cc578081fd5b81516126df6126da82613316565b6132ef565b818152915060208083019084810160005b84811015612755578151870188603f82011261270b57600080fd5b8381015161271b6126da82613336565b81815260408b8184860101111561273157600080fd5b6127408388840183870161335a565b508652505092820192908201906001016126f0565b505050505092915050565b60008083601f840112612771578182fd5b50813567ffffffffffffffff811115612788578182fd5b6020830191508360208285010111156127a057600080fd5b9250929050565b600082601f8301126127b7578081fd5b81356127c56126da82613336565b91508082528360208285010111156127dc57600080fd5b8060208401602084013760009082016020015292915050565b600060a08284031215612806578081fd5b61281060a06132ef565b905081358152602082013560208201526040820135604082015260608201356060820152608082013567ffffffffffffffff81111561284e57600080fd5b61285a848285016127a7565b60808301525092915050565b600060208284031215612877578081fd5b813561288281613386565b9392505050565b6000806040838503121561289b578081fd5b825167ffffffffffffffff808211156128b2578283fd5b81850186601f8201126128c3578384fd5b805192506128d36126da84613316565b80848252602080830192508084018a8283890287010111156128f3578788fd5b8794505b8685101561291e57805161290a81613386565b8452600194909401939281019281016128f7565b508801519096509350505080821115612935578283fd5b50612942858286016126bc565b9150509250929050565b60006020828403121561295d578081fd5b81518015158114612882578182fd5b60008060008060408587031215612981578182fd5b843567ffffffffffffffff80821115612998578384fd5b6129a488838901612760565b909650945060208701359150808211156129bc578384fd5b506129c987828801612760565b95989497509550505050565b6000602082840312156129e6578081fd5b813567ffffffffffffffff808211156129fd578283fd5b81840160608187031215612a0f578384fd5b612a1960606132ef565b9250803582811115612a29578485fd5b612a35878284016127f5565b845250602081013582811115612a49578485fd5b612a55878284016127f5565b602085015250604081013582811115612a6c578485fd5b612a78878284016127a7565b6040850152509195945050505050565b600060208284031215612a99578081fd5b5035919050565b600060208284031215612ab1578081fd5b5051919050565b600080600060408486031215612acc578283fd5b833560ff81168114612adc578384fd5b9250602084013567ffffffffffffffff811115612af7578283fd5b612b0386828701612760565b9497909650939450505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b60008151808452612b5281602086016020860161335a565b601f01601f19169290920160200192915050565b60008251612b7881846020870161335a565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b03929092168252602082015260400190565b901515815260200190565b6000602082526128826020830184612b3a565b600060408252612be1604083018688612b10565b8281036020840152612bf4818587612b10565b979650505050505050565b6020808252601f908201527f746865206d73672073656e646572206973206e6f7420612072656c6179657200604082015260600190565b6020808252601690820152751d1bdbc81bdb1908189b1bd8dac81a5b9d9bdb1d995960521b604082015260600190565b6020808252818101527f6d616c6963696f757320766f746520736c617368206e6f7420656e61626c6564604082015260600190565b60208082526019908201527f74686520636f6e7472616374206e6f7420696e69742079657400000000000000604082015260600190565b6020808252601a908201527f6e6f2076696f6c6174696f6e206f6620766f74652072756c6573000000000000604082015260600190565b6020808252818101527f7468652066656c6f6e795468726573686f6c64206f7574206f662072616e6765604082015260600190565b6020808252602b908201527f6c656e677468206f6620656e61626c654d616c6963696f7573566f7465536c6160408201526a0e6d040dad2e6dac2e8c6d60ab1b606082015260800190565b60208082526017908201527f766572696679207369676e6174757265206661696c6564000000000000000000604082015260600190565b6020808252600e908201526d696e70757420746f6f206c6f6e6760901b604082015260600190565b60208082526019908201527f7372634e756d20626967676572207468616e207461724e756d00000000000000604082015260600190565b6020808252602c908201527f7468652066696e616c69747920736c6173682072657761726420726174696f2060408201526b6f7574206f662072616e676560a01b606082015260800190565b60208082526027908201527f6c656e677468206f66206d697364656d65616e6f725468726573686f6c64206d6040820152660d2e6dac2e8c6d60cb1b606082015260800190565b60208082526013908201527274776f206964656e746963616c20766f74657360681b604082015260600190565b60208082526030908201527f746865206d6573736167652073656e646572206d7573742062652076616c696460408201526f185d1bdc94d95d0818dbdb9d1c9858dd60821b606082015260800190565b6020808252601190820152706164646974696f6e206f766572666c6f7760781b604082015260600190565b6020808252601490820152736761737072696365206973206e6f74207a65726f60601b604082015260600190565b6020808252602e908201527f746865206d6573736167652073656e646572206d75737420626520676f76657260408201526d1b985b98d94818dbdb9d1c9858dd60921b606082015260800190565b60208082526022908201527f6c656e677468206f662066656c6f6e795468726573686f6c64206d69736d61746040820152610c6d60f31b606082015260800190565b60208082526019908201527f74686520636f6e747261637420616c726561647920696e697400000000000000604082015260600190565b6020808252601a908201527f6c656e677468206973206c657373207468616e206f6666736574000000000000604082015260600190565b60208082526025908201527f746865206d697364656d65616e6f725468726573686f6c64206f7574206f662060408201526472616e676560d81b606082015260800190565b6020808252602f908201527f746865206d6573736167652073656e646572206d7573742062652063726f737360408201526e0818da185a5b8818dbdb9d1c9858dd608a1b606082015260800190565b6020808252602d908201527f746865206d6573736167652073656e646572206d75737420626520746865206260408201526c3637b1b590383937b23ab1b2b960991b606082015260800190565b6020808252600d908201526c756e6b6e6f776e20706172616d60981b604082015260600190565b6020808252601e908201527f7265636569766520756e65787065637465642073796e207061636b6167650000604082015260600190565b6020808252602b908201527f6c656e677468206f662066696e616c697479536c61736852657761726452617460408201526a0d2de40dad2e6dac2e8c6d60ab1b606082015260800190565b6020808252818101527f63616e206e6f7420736c61736820747769636520696e206f6e6520626c6f636b604082015260600190565b61ffff91909116815260200190565b90815260200190565b6000838252604060208301526132766040830184612b3a565b949350505050565b918252602082015260400190565b92835260208301919091521515604082015260600190565b63ffffffff91909116815260200190565b60ff91909116815260200190565b600060ff85168252606060208301526132df6060830185612b3a565b9050826040830152949350505050565b60405181810167ffffffffffffffff8111828210171561330e57600080fd5b604052919050565b600067ffffffffffffffff82111561332c578081fd5b5060209081020190565b600067ffffffffffffffff82111561334c578081fd5b50601f01601f191660200190565b60005b8381101561337557818101518382015260200161335d565b838111156116945750506000910152565b6001600160a01b038116811461339b57600080fd5b5056fea2646970667358221220f826c2f80c6807c5df53c6cfe5be2e59ad7e87dad138f63f83dd1caf79118d6064736f6c63430006040033", + }, + { + ContractAddr: common.HexToAddress(SystemRewardContract), + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/b144718e94d7a1ebb24a7103202300f08826f369", + Code: "6080604052600436106101a05760003560e01c80637942fd05116100ec578063ac4317511161008a578063f9a2bbc711610064578063f9a2bbc714610550578063fb5478b314610565578063fc3e59081461057a578063fd6a68791461058f576101e4565b8063ac43175114610457578063c81b166214610526578063dc927faf1461053b576101e4565b80639dc09262116100c65780639dc0926214610403578063a1a11bf514610418578063a78abc161461042d578063ab51bb9614610442576101e4565b80637942fd05146103a057806396713da9146103b55780639a99b4f0146103ca576101e4565b80634bf6c882116101595780636e47b482116101335780636e47b4821461034c57806370fd5bad14610361578063718a8aa81461037657806375d47a0a1461038b576101e4565b80634bf6c882146102db57806351e80672146102f05780636d70f7ae14610305576101e4565b80630bee7a67146101e95780630e2374a5146102175780633a0b0eff146102485780633dffc3871461026f57806343756e5c1461029a578063493279b1146102af576101e4565b366101e45734156101e25760408051348152905133917f6c98249d85d88c3753a04a22230f595e4dc8d3dc86c34af35deeeedc861b89db919081900360200190a25b005b600080fd5b3480156101f557600080fd5b506101fe6105a4565b6040805163ffffffff9092168252519081900360200190f35b34801561022357600080fd5b5061022c6105a9565b604080516001600160a01b039092168252519081900360200190f35b34801561025457600080fd5b5061025d6105af565b60408051918252519081900360200190f35b34801561027b57600080fd5b506102846105b5565b6040805160ff9092168252519081900360200190f35b3480156102a657600080fd5b5061022c6105ba565b3480156102bb57600080fd5b506102c46105c0565b6040805161ffff9092168252519081900360200190f35b3480156102e757600080fd5b506102846105c5565b3480156102fc57600080fd5b5061022c6105ca565b34801561031157600080fd5b506103386004803603602081101561032857600080fd5b50356001600160a01b03166105d0565b604080519115158252519081900360200190f35b34801561035857600080fd5b5061022c6105ee565b34801561036d57600080fd5b506102846105f4565b34801561038257600080fd5b506102846105f9565b34801561039757600080fd5b5061022c6105fe565b3480156103ac57600080fd5b50610284610604565b3480156103c157600080fd5b50610284610609565b3480156103d657600080fd5b5061025d600480360360408110156103ed57600080fd5b506001600160a01b03813516906020013561060e565b34801561040f57600080fd5b5061022c6107b9565b34801561042457600080fd5b5061022c6107bf565b34801561043957600080fd5b506103386107c5565b34801561044e57600080fd5b506101fe6107ce565b34801561046357600080fd5b506101e26004803603604081101561047a57600080fd5b81019060208101813564010000000081111561049557600080fd5b8201836020820111156104a757600080fd5b803590602001918460018302840111640100000000831117156104c957600080fd5b9193909290916020810190356401000000008111156104e757600080fd5b8201836020820111156104f957600080fd5b8035906020019184600183028401116401000000008311171561051b57600080fd5b5090925090506107d3565b34801561053257600080fd5b5061022c610b56565b34801561054757600080fd5b5061022c610b5c565b34801561055c57600080fd5b5061022c610b62565b34801561057157600080fd5b5061025d610b68565b34801561058657600080fd5b50610284610b74565b34801561059b57600080fd5b5061022c610b79565b606481565b61200181565b60015481565b600181565b61100181565b606181565b600881565b61200081565b6001600160a01b031660009081526002602052604090205460ff1690565b61100581565b600281565b601081565b61100881565b600b81565b600981565b6000805460ff1661068b57600260208190527fe57bda0a954a7c7381b17b2c763e646ba2c60f67292d287ba583603e2c1c41668054600160ff19918216811790925561100560009081527fe25235fc0de9d7165652bef0846fefda506174abb9a190f03d0f7bcc6146dbce80548316841790559282558254161790555b3360009081526002602052604090205460ff166106d95760405162461bcd60e51b815260040180806020018281038252602b815260200180610c67602b913960400191505060405180910390fd5b60004783106106e857476106ea565b825b9050670de0b6b3a76400008111156107075750670de0b6b3a76400005b8015610788576040516001600160a01b0385169082156108fc029083906000818181858888f19350505050158015610743573d6000803e3d6000fd5b506040805182815290516001600160a01b038616917ff8b71c64315fc33b2ead2adfa487955065152a8ac33d9d5193aafd7f45dc15a0919081900360200190a26107b2565b6040517fe589651933c2457488cc0d8e0941518abf748e799435e4e396d9c4d0b2db2d4d90600090a15b9392505050565b61100781565b61100681565b60005460ff1681565b600081565b33611007146108135760405162461bcd60e51b815260040180806020018281038252602e815260200180610cc1602e913960400191505060405180910390fd5b61087584848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600b81526a30b23227b832b930ba37b960a91b60208201529150610b7f9050565b1561094d57606082828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050825192935050601490911490506108f85760405162461bcd60e51b815260040180806020018281038252602c815260200180610cef602c913960400191505060405180910390fd5b60148101516001600160a01b038116600081815260026020526040808220805460ff19166001179055517f9870d7fe5d112134c55844951dedf365363006d9c588db07c4c85af6322a06199190a25050610ac4565b6109b284848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600e81526d3232b632ba32a7b832b930ba37b960911b60208201529150610b7f9050565b15610a8757606082828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505082519293505060149091149050610a355760405162461bcd60e51b815260040180806020018281038252602f815260200180610c92602f913960400191505060405180910390fd5b60148101516001600160a01b038116600081815260026020526040808220805460ff19169055517fb40992a19dba61ea600e87fce607102bf5908dc89076217b6ca6ae195224f7029190a25050610ac4565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b61100281565b61100381565b61100081565b670de0b6b3a764000081565b600381565b61100481565b6000816040516020018082805190602001908083835b60208310610bb45780518252601f199092019160209182019101610b95565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b60208310610c225780518252601f199092019160209182019101610c03565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051602081830303815290604052805190602001201490509291505056fe6f6e6c79206f70657261746f7220697320616c6c6f77656420746f2063616c6c20746865206d6574686f646c656e677468206f662076616c756520666f722064656c6574654f70657261746f722073686f756c64206265203230746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e74726163746c656e677468206f662076616c756520666f72206164644f70657261746f722073686f756c64206265203230a26469706673582212205c998ac20925f17d8af20803f32be2cf1698c9a844de45001ca5ed8c879cc93f64736f6c63430006040033", + }, + { + ContractAddr: common.HexToAddress(RelayerHubContract), + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/b144718e94d7a1ebb24a7103202300f08826f369", + Code: "608060405234801561001057600080fd5b50600436106102275760003560e01c80638f83ab1311610130578063c81b1662116100b8578063f3ae24151161007c578063f3ae2415146104e8578063f9a2bbc71461050e578063fc3e590814610516578063fd30d9b81461051e578063fd6a68791461052657610227565b8063c81b1662146104c0578063dc927faf146104c8578063dd91d1c5146104d0578063e1c7392a146104d8578063e79a198f146104e057610227565b8063a1a11bf5116100ff578063a1a11bf5146103de578063a74b83ca146103e6578063a78abc16146103ee578063ab51bb96146103f6578063ac431751146103fe57610227565b80638f83ab13146103a057806395468d26146103c657806396713da9146103ce5780639dc09262146103d657610227565b8063541d5548116101b3578063718a8aa811610182578063718a8aa81461034857806375d47a0a1461035057806378beee67146103585780637942fd051461037e5780637ae230881461038657610227565b8063541d5548146102d85780636a6a419e146103125780636e47b4821461033857806370fd5bad1461034057610227565b80633dffc387116101fa5780633dffc3871461028357806343756e5c146102a1578063493279b1146102a95780634bf6c882146102c857806351e80672146102d057610227565b806303aff02b1461022c578063049a5716146102365780630bee7a671461025a5780630e2374a51461027b575b600080fd5b61023461052e565b005b61023e610539565b604080516001600160a01b039092168252519081900360200190f35b610262610551565b6040805163ffffffff9092168252519081900360200190f35b61023e610556565b61028b61055c565b6040805160ff9092168252519081900360200190f35b61023e610561565b6102b1610567565b6040805161ffff9092168252519081900360200190f35b61028b61056c565b61023e610571565b6102fe600480360360208110156102ee57600080fd5b50356001600160a01b0316610577565b604080519115158252519081900360200190f35b6102fe6004803603602081101561032857600080fd5b50356001600160a01b0316610595565b61023e6105b3565b61028b6105b9565b61028b6105be565b61023e6105c3565b6102346004803603602081101561036e57600080fd5b50356001600160a01b03166105c9565b61028b6107b1565b61038e6107b6565b60408051918252519081900360200190f35b610234600480360360208110156103b657600080fd5b50356001600160a01b03166107c3565b61038e610a02565b61028b610a0e565b61023e610a13565b61023e610a19565b61023e610a1f565b6102fe610a37565b610262610a40565b6102346004803603604081101561041457600080fd5b81019060208101813564010000000081111561042f57600080fd5b82018360208201111561044157600080fd5b8035906020019184600183028401116401000000008311171561046357600080fd5b91939092909160208101903564010000000081111561048157600080fd5b82018360208201111561049357600080fd5b803590602001918460018302840111640100000000831117156104b557600080fd5b509092509050610a45565b61023e610d96565b61023e610d9c565b610234610da2565b610234610e43565b610234610ec5565b6102fe600480360360208110156104fe57600080fd5b50356001600160a01b031661107e565b61023e61109c565b61028b6110a2565b6102fe6110a7565b61023e6110b0565b610537336110b6565b565b739fb29aac15b9a4b7f17c3385939b007540f4d79181565b606481565b61200181565b600181565b61100181565b606181565b600881565b61200081565b6001600160a01b031660009081526007602052604090205460ff1690565b6001600160a01b031660009081526008602052604090205460ff1690565b61100581565b600281565b601081565b61100881565b3360009081526008602052604090205460ff166106175760405162461bcd60e51b81526004018080602001828103825260248152602001806115c26024913960400191505060405180910390fd5b61062033611218565b1561065c5760405162461bcd60e51b815260040180806020018281038252602181526020018061157f6021913960400191505060405180910390fd5b3233146106b0576040805162461bcd60e51b815260206004820152601e60248201527f70726f766973696f6e616c2072656c6179657220697320612070726f78790000604482015290519081900360640190fd5b6001600160a01b038181166000908152600960205260409020541633146107085760405162461bcd60e51b815260040180806020018281038252602781526020018061163b6027913960400191505060405180910390fd5b6001600160a01b03818116600081815260066020908152604080832080543380865260078086528487208054600160ff199182161790915584546001600160a01b031990811684179095556008875285882080548216905597875260098652848720805490941690935596168085529083529281902080549094169093558251828152908101939093528151909260008051602061166283398151915292908290030190a15050565b600b81565b68056bc75e2d6310000081565b3360009081526005602052604090205460ff16610820576040805162461bcd60e51b81526020600482015260166024820152751b585b9859d95c88191bd95cc81b9bdd08195e1a5cdd60521b604482015290519081900360640190fd5b61082981611218565b156108655760405162461bcd60e51b81526004018080602001828103825260278152602001806115e66027913960400191505060405180910390fd5b6001600160a01b03811615610921576001600160a01b03811660009081526007602052604090205460ff16156108db576040805162461bcd60e51b815260206004820152601660248201527572656c6179657220616c72656164792065786973747360501b604482015290519081900360640190fd5b6001600160a01b0381166000818152600860209081526040808320805460ff191660011790553383526009909152902080546001600160a01b03191690911790556109c2565b3360008181526006602090815260408083208054600980855283862080546001600160a01b03198085169095556001600160a01b0393841680895260078852868920805460ff19908116909155918516808a5260088952878a20805490931690925598909752908552805490921690915581518581529086169281019290925280516000805160206116628339815191529281900390910190a150506109ff565b604080516001600160a01b038316815290517ffba56633276570c7d3120d4535bf3bce26523da53958e40734210b9fd99b36939181900360200190a15b50565b67016345785d8a000081565b600981565b61100781565b61100681565b7337b8516a0f88e65d677229b402ec6c1e0e33300481565b60005460ff1681565b600081565b60005460ff16610a98576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b3361100714610ad85760405162461bcd60e51b815260040180806020018281038252602e81526020018061160d602e913960400191505060405180910390fd5b610b3984848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600a81526930b23226b0b730b3b2b960b11b6020820152915061121e9050565b15610bd15760148114610b7d5760405162461bcd60e51b81526004018080602001828103825260228152602001806115a06022913960400191505060405180910390fd5b6000610bc0601484848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061130592505050565b9050610bcb8161130a565b50610d04565b610c3584848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600d81526c3932b6b7bb32a6b0b730b3b2b960991b6020820152915061121e9050565b15610cc75760148114610c795760405162461bcd60e51b81526004018080602001828103825260228152602001806115a06022913960400191505060405180910390fd5b6000610cbc601484848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061130592505050565b9050610bcb816110b6565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b61100281565b61100381565b600a5460ff1615610dfa576040805162461bcd60e51b815260206004820152601e60248201527f7468652077686974656c6973747320616c726561647920757064617465640000604482015290519081900360640190fd5b610e17739fb29aac15b9a4b7f17c3385939b007540f4d7916113cc565b610e347337b8516a0f88e65d677229b402ec6c1e0e3330046113cc565b600a805460ff19166001179055565b60005460ff1615610e9b576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b68056bc75e2d63100000600190815567016345785d8a00006002556000805460ff19169091179055565b3360009081526004602052604090205460ff16610f20576040805162461bcd60e51b81526020600482015260146024820152731c995b185e595c88191bc81b9bdd08195e1a5cdd60621b604482015290519081900360640190fd5b60005460ff16610f73576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b610f7b611564565b5033600081815260036020908152604091829020825180840190935280548084526001909101549183018290529192916108fc91610fbf919063ffffffff61148416565b6040518115909202916000818181858888f19350505050158015610fe7573d6000803e3d6000fd5b50602081015160405161100291829181156108fc0291906000818181858888f1935050505015801561101d573d6000803e3d6000fd5b50336000818152600460209081526040808320805460ff191690556003825280832083815560010192909255815192835290517fd17202129b83db7880d6b9f25df81c58ad46f7e0e2c92236b1aa10663a4876679281900390910190a15050565b6001600160a01b031660009081526005602052604090205460ff1690565b61100081565b600381565b600a5460ff1681565b61100481565b6001600160a01b03811660009081526005602052604090205460ff1661111b576040805162461bcd60e51b81526020600482015260156024820152741b585b9859d95c88191bd95cdb89dd08195e1a5cdd605a1b604482015290519081900360640190fd5b6001600160a01b038082166000818152600660209081526040808320805460058452828520805460ff1990811690915582546001600160a01b0319908116909355600980865284872080548a16885260088752858820805490931690925595879052948452845490911690935580519384525191909316927f2002866d443ac6c241fecaaa2af4895828c7de2cc423b9d01f7969650f557c76928290030190a16001600160a01b03811615611214576001600160a01b0381166000818152600760209081526040808320805460ff1916905580519384529083019190915280516000805160206116628339815191529281900390910190a15b5050565b3b151590565b6000816040516020018082805190602001908083835b602083106112535780518252601f199092019160209182019101611234565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b602083106112c15780518252601f1990920191602091820191016112a2565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b015190565b6001600160a01b03811660009081526005602052604090205460ff1615611371576040805162461bcd60e51b81526020600482015260166024820152756d616e6167657220616c72656164792065786973747360501b604482015290519081900360640190fd5b6001600160a01b038116600081815260056020908152604091829020805460ff19166001179055815192835290517fe0de8e71a22c046647f4ef744348fa126ad6d052d4ce070999481f69d45575179281900390910190a150565b6001600160a01b03811660008181526005602090815260408083208054600160ff1991821681179092556006845282852080546001600160a01b031916871790556007845293829020805490941617909255815192835290517fe0de8e71a22c046647f4ef744348fa126ad6d052d4ce070999481f69d45575179281900390910190a160408051600081526001600160a01b03831660208201528151600080516020611662833981519152929181900390910190a150565b60006114c683836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506114cd565b9392505050565b6000818484111561155c5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015611521578181015183820152602001611509565b50505050905090810190601f16801561154e5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b60405180604001604052806000815260200160008152509056fe70726f766973696f6e616c2072656c61796572206973206120636f6e74726163746c656e677468206f66206d616e616765722061646472657373206d69736d6174636872656c61796572206973206e6f7420612070726f766973696f6e616c2072656c61796572636f6e7472616374206973206e6f7420616c6c6f77656420746f20626520612072656c61796572746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e747261637470726f766973696f6e616c206973206e6f742073657420666f722074686973206d616e61676572a5a19d7e9dab30a215022382d7abe782b579986fcbedec9942ecd0db9510a148a2646970667358221220e87e5b6ca8388e14d2ec9c2453581b5e2346a0aaa8fa61707f4d522357ac45d464736f6c63430006040033", + }, + { + ContractAddr: common.HexToAddress(CrossChainContract), + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/b144718e94d7a1ebb24a7103202300f08826f369", + Code: "608060405234801561001057600080fd5b50600436106103995760003560e01c8063718a8aa8116101e9578063c27cdcfb1161010f578063dc927faf116100ad578063f7a251d71161007c578063f7a251d714610b2f578063f9a2bbc714610ba7578063fc3e590814610baf578063fd6a687914610bb757610399565b8063dc927faf14610af7578063e1c7392a14610aff578063e3b0480514610b07578063e6400bbe14610b2757610399565b8063ccc108d7116100e9578063ccc108d714610ab0578063d31f968d14610ab8578063d76a867514610ae7578063dc40433114610aef57610399565b8063c27cdcfb14610a80578063c780e9de14610aa0578063c81b166214610aa857610399565b80638cc8f56111610187578063a78abc1611610156578063a78abc16146109b2578063ab51bb96146109ba578063ac431751146109c2578063b0355f5b1461078157610399565b80638cc8f5611461088757806396713da91461099a5780639dc09262146109a2578063a1a11bf5146109aa57610399565b806375d47a0a116101c357806375d47a0a146108a75780637942fd05146108af57806384013b6a146108b7578063863fe4ab1461099257610399565b8063718a8aa81461088f578063719482d51461089757806374f079b81461089f57610399565b8063422f9050116102ce57806363e1394e1161026c5780636de380bd1161023b5780636de380bd146108575780636e47a51a1461085f5780636e47b4821461087f57806370fd5bad1461088757610399565b806363e1394e146107ff5780636a3cb34d146108075780636bacff2c1461080f5780636c46aa681461080757610399565b80634bf6c882116102a85780634bf6c882146107b957806351e80672146107c15780635692ddd3146107c95780635f832177146107d157610399565b8063422f90501461078957806343756e5c146107a9578063493279b1146107b157610399565b8063299b533d1161033b578063308325f411610315578063308325f4146106155780633a648b151461061d5780633bdc47a6146106595780633dffc3871461078157610399565b8063299b533d146105a35780632af6f399146105d75780632ff32aea146105f457610399565b806314b3023b1161037757806314b3023b146104015780631d1309351461041b5780631e275ae11461043757806322556cdc1461059b57610399565b806305e682581461039e5780630bee7a67146103bc5780630e2374a5146103dd575b600080fd5b6103a6610bbf565b6040805160ff9092168252519081900360200190f35b6103c4610bc4565b6040805163ffffffff9092168252519081900360200190f35b6103e5610bc9565b604080516001600160a01b039092168252519081900360200190f35b610409610bcf565b60408051918252519081900360200190f35b610423610bd5565b604080519115158252519081900360200190f35b610599600480360361010081101561044e57600080fd5b81018160a081016080820135600160201b81111561046b57600080fd5b82018360208201111561047d57600080fd5b803590602001918460018302840111600160201b8311171561049e57600080fd5b919390929091602081019035600160201b8111156104bb57600080fd5b8201836020820111156104cd57600080fd5b803590602001918460018302840111600160201b831117156104ee57600080fd5b919390929091602081019035600160201b81111561050b57600080fd5b82018360208201111561051d57600080fd5b803590602001918460018302840111600160201b8311171561053e57600080fd5b919390929091602081019035600160201b81111561055b57600080fd5b82018360208201111561056d57600080fd5b803590602001918460018302840111600160201b8311171561058e57600080fd5b509092509050610bde565b005b6104096112c2565b6105c0600480360360208110156105b957600080fd5b50356112c7565b6040805161ffff9092168252519081900360200190f35b610423600480360360208110156105ed57600080fd5b50356112dd565b6105fc6112f2565b60408051600792830b90920b8252519081900360200190f35b6104096112fb565b61063d6004803603602081101561063357600080fd5b503560ff16611301565b604080516001600160401b039092168252519081900360200190f35b61070c6004803603606081101561066f57600080fd5b60ff82351691602081013591810190606081016040820135600160201b81111561069857600080fd5b8201836020820111156106aa57600080fd5b803590602001918460018302840111600160201b831117156106cb57600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061131c945050505050565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561074657818101518382015260200161072e565b50505050905090810190601f1680156107735780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6103a6611392565b6104236004803603602081101561079f57600080fd5b503560ff16611397565b6103e56113ac565b6105c06113b2565b6103a66113b7565b6103e56113bc565b6104096113c2565b610599600480360360408110156107e757600080fd5b506001600160a01b03813581169160200135166113f2565b610409611652565b6105c061167a565b61082c6004803603602081101561082557600080fd5b503561167f565b6040805161ffff90941684526001600160801b03909216602084015282820152519081900360600190f35b6104096116ae565b6103e56004803603602081101561087557600080fd5b503560ff166116d5565b6103e56116f0565b6103a661167a565b6103a66116f6565b6105c0611392565b6104096116fb565b6103e5611701565b6103a6611707565b610599600480360360a08110156108cd57600080fd5b810190602081018135600160201b8111156108e757600080fd5b8201836020820111156108f957600080fd5b803590602001918460018302840111600160201b8311171561091a57600080fd5b919390929091602081019035600160201b81111561093757600080fd5b82018360208201111561094957600080fd5b803590602001918460018302840111600160201b8311171561096a57600080fd5b919350915080356001600160401b03908116916020810135909116906040013560ff1661170c565b6104096129c6565b6103a66129ce565b6103e56129d3565b6103e56129d9565b6104236129df565b6103c4610bbf565b610599600480360360408110156109d857600080fd5b810190602081018135600160201b8111156109f257600080fd5b820183602082011115610a0457600080fd5b803590602001918460018302840111600160201b83111715610a2557600080fd5b919390929091602081019035600160201b811115610a4257600080fd5b820183602082011115610a5457600080fd5b803590602001918460018302840111600160201b83111715610a7557600080fd5b5090925090506129e8565b61063d60048036036020811015610a9657600080fd5b503560ff166134ac565b6104096134c7565b6103e56134eb565b6105996134f1565b61042360048036036040811015610ace57600080fd5b5080356001600160a01b0316906020013560ff16613745565b61070c613765565b610409613784565b6103e561378a565b610599613790565b61063d60048036036020811015610b1d57600080fd5b503560ff16613b47565b610599613b62565b61059960048036036060811015610b4557600080fd5b60ff8235169190810190604081016020820135600160201b811115610b6957600080fd5b820183602082011115610b7b57600080fd5b803590602001918460018302840111600160201b83111715610b9c57600080fd5b919350915035613d81565b6103e5613ec4565b6103a6613eca565b6103e5613ecf565b600081565b606481565b61200181565b60015481565b600b5460ff1681565b60005460ff16610c23576040805162461bcd60e51b815260206004820152601960248201526000805160206149b2833981519152604482015290519081900360640190fd5b604080516337d7f9c160e21b81526001600160401b038b35166004820181905291516110039163df5fe704916024808301926020929190829003018186803b158015610c6e57600080fd5b505afa158015610c82573d6000803e3d6000fd5b505050506040513d6020811015610c9857600080fd5b5051610cd55760405162461bcd60e51b81526004018080602001828103825260238152602001806149d26023913960400191505060405180910390fd5b604080516337d7f9c160e21b815260208c8101356001600160401b03166004830181905292516110039263df5fe704926024808301939192829003018186803b158015610d2157600080fd5b505afa158015610d35573d6000803e3d6000fd5b505050506040513d6020811015610d4b57600080fd5b5051610d885760405162461bcd60e51b81526004018080602001828103825260238152602001806149d26023913960400191505060405180910390fd5b60608b013560ff81166000908152600560205260409020546001600160401b03909116906001600160a01b0316610e01576040805162461bcd60e51b815260206004820152601860248201527718da185b9b995b081a5cc81b9bdd081cdd5c1c1bdc9d195960421b604482015290519081900360640190fd5b600b5460ff1615610e45576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b8888604051808383808284376040519201829003822094508f93508e9250819050838380828437808301925050509250505060405180910390201415610ec1576040805162461bcd60e51b815260206004820152600c60248201526b1cd85b59481c185e5b1bd85960a21b604482015290519081900360640190fd5b60606001600160401b0360408e01358116908e83013516610ee28282613ed5565b80516020808301919091206000818152600e9092526040909120549194509060ff1615610f4b576040805162461bcd60e51b8152602060048201526012602482015271185b1c9958591e4818da185b1b195b99d95960721b604482015290519081900360640190fd5b6000908152600e60205260408120805460ff191660011790558f8160200201356001600160401b0316905060608f8f8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050905060608c8c8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052506040805163cba510a960e01b81526001600160401b038a16600482015290519596509094611003945063cba510a9935060248083019350602092829003018186803b15801561104157600080fd5b505afa158015611055573d6000803e3d6000fd5b505050506040513d602081101561106b57600080fd5b505160408051808201909152600381526269626360e81b6020820152909150611098908290898686613f1d565b6110e1576040805162461bcd60e51b81526020600482015260156024820152740696e76616c6964206d65726b6c652070726f6f663605c1b604482015290519081900360640190fd5b5050505060008f6001600481106110f457fe5b60200201356001600160401b0316905060608d8d8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8f018190048102820181019092528d815293945060609392508d91508c908190840183828082843760009201829052506040805163cba510a960e01b81526001600160401b038a16600482015290519596509094611003945063cba510a9935060248083019350602092829003018186803b1580156111c057600080fd5b505afa1580156111d4573d6000803e3d6000fd5b505050506040513d60208110156111ea57600080fd5b505160408051808201909152600381526269626360e81b6020820152909150611217908290898686613f1d565b611260576040805162461bcd60e51b8152602060048201526015602482015274696e76616c6964206d65726b6c652070726f6f663160581b604482015290519081900360640190fd5b5050505061126c61401a565b604080516001600160401b038416815260ff83166020820152815133927f039eb91179ffd7d3b6e97f8ea106e748e827f910b872375dbc9c14a362319c3c928290030190a2505050505050505050505050505050565b603281565b600d6020526000908152604090205461ffff1681565b600e6020526000908152604090205460ff1681565b60045460070b81565b60025481565b600a602052600090815260409020546001600160401b031681565b60606000825160210190506060816040519080825280601f01601f191660200182016040528015611354576020820181803683370190505b506021810186905260018101879052828152905060418101600061137786614098565b509050611386818388516140a2565b50909695505050505050565b600181565b60096020526000908152604090205460ff1681565b61100181565b606181565b600881565b61200081565b604080517710d05390d15317d514905394d1915497d41493d413d4d05360421b8152905190819003601801902081565b60005460ff16611437576040805162461bcd60e51b815260206004820152601960248201526000805160206149b2833981519152604482015290519081900360640190fd5b6040805163569e4ed360e11b815233600482015290516000916110009163ad3c9da691602480820192602092909190829003018186803b15801561147a57600080fd5b505afa15801561148e573d6000803e3d6000fd5b505050506040513d60208110156114a457600080fd5b505160408051633d42651560e11b8152905191925060009161100091637a84ca2a916004808301926020929190829003018186803b1580156114e557600080fd5b505afa1580156114f9573d6000803e3d6000fd5b505050506040513d602081101561150f57600080fd5b505190508061151c575060155b60008211801561152c5750808211155b61156b576040805162461bcd60e51b815260206004820152600b60248201526a1b9bdd0818d8589a5b995d60aa1b604482015290519081900360640190fd5b604080516001600160a01b038087166020808401919091529086168284015282518083038401815260608301808552815191909201207710d05390d15317d514905394d1915497d41493d413d4d05360421b90915291519081900360780190206000906115d890836140e3565b9050801561164a5760408051630911a2c160e11b81526001600160a01b03888116600483015287166024820152905161100491631223458291604480830192600092919082900301818387803b15801561163157600080fd5b505af1158015611645573d6000803e3d6000fd5b505050505b505050505050565b604080516f14d554d411539117d41493d413d4d05360821b8152905190819003601001902081565b600281565b600c602052600090815260409020805460019091015461ffff8216916201000090046001600160801b03169083565b604080516e149153d4115397d41493d413d4d053608a1b8152905190819003600f01902081565b6005602052600090815260409020546001600160a01b031681565b61100581565b601081565b60035481565b61100881565b600b81565b60005460ff16611751576040805162461bcd60e51b815260206004820152601960248201526000805160206149b2833981519152604482015290519081900360640190fd5b60408051630a83aaa960e31b815233600482015290516110069163541d5548916024808301926020929190829003018186803b15801561179057600080fd5b505afa1580156117a4573d6000803e3d6000fd5b505050506040513d60208110156117ba57600080fd5b505161180d576040805162461bcd60e51b815260206004820152601f60248201527f746865206d73672073656e646572206973206e6f7420612072656c6179657200604482015290519081900360640190fd5b60ff8116600090815260086020526040902054829082906001600160401b03908116908316811461187d576040805162461bcd60e51b815260206004820152601560248201527439b2b8bab2b731b2903737ba1034b71037b93232b960591b604482015290519081900360640190fd5b60ff8216600090815260086020908152604091829020805467ffffffffffffffff1916600185016001600160401b039081169190911790915582516337d7f9c160e21b81529089166004820152915188926110039263df5fe70492602480840193829003018186803b1580156118f257600080fd5b505afa158015611906573d6000803e3d6000fd5b505050506040513d602081101561191c57600080fd5b50516119595760405162461bcd60e51b81526004018080602001828103825260238152602001806149d26023913960400191505060405180910390fd5b60ff851660009081526005602052604090205485906001600160a01b03166119c3576040805162461bcd60e51b815260206004820152601860248201527718da185b9b995b081a5cc81b9bdd081cdd5c1c1bdc9d195960421b604482015290519081900360640190fd5b60ff86166000908152600a6020526040902054889087906001600160401b039081169083161015611a2c576040805162461bcd60e51b815260206004820152600e60248201526d3a37b79037b632103432b0b232b960911b604482015290519081900360640190fd5b60ff81166000908152600a60205260409020546001600160401b03838116911614611a7e5760ff81166000908152600a60205260409020805467ffffffffffffffff19166001600160401b0384161790555b600b5460ff1615611ac2576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b60608e8e8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050905060608d8d8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509050611c066110036001600160a01b031663cba510a98e6040518263ffffffff1660e01b815260040180826001600160401b03166001600160401b0316815260200191505060206040518083038186803b158015611baf57600080fd5b505afa158015611bc3573d6000803e3d6000fd5b505050506040513d6020811015611bd957600080fd5b505160408051808201909152600381526269626360e81b6020820152611bff8e8e613ed5565b8585613f1d565b611c4e576040805162461bcd60e51b815260206004820152601460248201527334b73b30b634b21036b2b935b63290383937b7b360611b604482015290519081900360640190fd5b60408051631bb5062960e31b81526001600160401b038e16600482015290516000916110039163dda8314891602480820192602092909190829003018186803b158015611c9a57600080fd5b505afa158015611cae573d6000803e3d6000fd5b505050506040513d6020811015611cc457600080fd5b505190508b8b600080806060611cd9896143c8565b935093509350935083611d9b578460ff16866001600160401b03167ff7b2e42d694eb1100184aae86d4245d9e46966100b1dc7e723275b98326854ac8b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015611d53578181015183820152602001611d3b565b50505050905090810190601f168015611d805780820380516001836020036101000a031916815260200191505b509250505060405180910390a35050505050505050506129b6565b6040805160ff85811682529151918716916001600160401b038916917f36afdaf439a8f43fe72135135d804ae620b37a474f0943b5b85f6788312cad40919081900360200190a360ff83166123205760ff85166000818152600560209081526040808320548151631182b87560e01b815260048101958652602481019283528651604482015286516001600160a01b03909216958695631182b875958d958a9593949093606490910192918601918190849084905b83811015611e68578181015183820152602001611e50565b50505050905090810190601f168015611e955780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b158015611eb557600080fd5b505af1925050508015611f9957506040513d6000823e601f3d908101601f191682016040526020811015611ee857600080fd5b8101908080516040519392919084600160201b821115611f0757600080fd5b908301906020820185811115611f1c57600080fd5b8251600160201b811182820188101715611f3557600080fd5b82525081516020918201929091019080838360005b83811015611f62578181015183820152602001611f4a565b50505050905090810190601f168015611f8f5780820380516001836020036101000a031916815260200191505b5060405250505060015b6122ab576040516000815260443d1015611fb557506000612050565b60046000803e60005160e01c6308c379a08114611fd6576000915050612050565b60043d036004833e81513d60248201116001600160401b038211171561200157600092505050612050565b80830180516001600160401b03811115612022576000945050505050612050565b8060208301013d860181111561204057600095505050505050612050565b601f01601f191660405250925050505b8061205b575061216d565b60ff8716600090815260076020526040812054612092916001600160401b0390911690899061208d906002908861131c565b614478565b60ff8716600090815260076020908152604080832080546001600160401b038082166001011667ffffffffffffffff19909116179055805182815284518184015284516001600160a01b038716947ff91a8f63e5b3e0e89e5f93e1915a7805f3c52d9a73b3c09769785c2c7bf87acf948794849390840192918601918190849084905b8381101561212d578181015183820152602001612115565b50505050905090810190601f16801561215a5780820380516001836020036101000a031916815260200191505b509250505060405180910390a2506122a6565b3d808015612197576040519150601f19603f3d011682016040523d82523d6000602084013e61219c565b606091505b5060ff87166000908152600760205260408120546121cf916001600160401b0390911690899061208d906002908861131c565b60ff8716600090815260076020908152604080832080546001600160401b038082166001011667ffffffffffffffff19909116179055805182815284518184015284516001600160a01b038716947f63ac299d6332d1cc4e61b81e59bc00c0ac7c798addadf33840f1307cd2977351948794849390840192918601918190849084905b8381101561226a578181015183820152602001612252565b50505050905090810190601f1680156122975780820380516001836020036101000a031916815260200191505b509250505060405180910390a2505b61231a565b8051156123185760ff87166000908152600760205260408120546122e4916001600160401b0390911690899061208d906001908661131c565b60ff8716600090815260076020526040902080546001600160401b038082166001011667ffffffffffffffff199091161790555b505b506128ee565b60ff8316600114156125c45760ff8516600081815260056020908152604080832054815163831d65d160e01b815260048101958652602481019283528651604482015286516001600160a01b0390921695869563831d65d1958d958a9593949093606490910192918601918190849084905b838110156123aa578181015183820152602001612392565b50505050905090810190601f1680156123d75780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b1580156123f757600080fd5b505af1925050508015612408575060015b61231a576040516000815260443d1015612424575060006124bf565b60046000803e60005160e01c6308c379a081146124455760009150506124bf565b60043d036004833e81513d60248201116001600160401b0382111715612470576000925050506124bf565b80830180516001600160401b038111156124915760009450505050506124bf565b8060208301013d86018111156124af576000955050505050506124bf565b601f01601f191660405250925050505b806124ca575061252f565b60408051602080825283518183015283516001600160a01b038616937ff91a8f63e5b3e0e89e5f93e1915a7805f3c52d9a73b3c09769785c2c7bf87acf938693909283928301918501908083836000831561212d578181015183820152602001612115565b3d808015612559576040519150601f19603f3d011682016040523d82523d6000602084013e61255e565b606091505b5060408051602080825283518183015283516001600160a01b038616937f63ac299d6332d1cc4e61b81e59bc00c0ac7c798addadf33840f1307cd2977351938693909283928301918501908083836000831561226a578181015183820152602001612252565b60ff8316600214156128ee5760ff8516600081815260056020908152604080832054815163c8509d8160e01b815260048101958652602481019283528651604482015286516001600160a01b0390921695869563c8509d81958d958a9593949093606490910192918601918190849084905b8381101561264e578181015183820152602001612636565b50505050905090810190601f16801561267b5780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b15801561269b57600080fd5b505af19250505080156126ac575060015b6128ec576040516000815260443d10156126c857506000612763565b60046000803e60005160e01c6308c379a081146126e9576000915050612763565b60043d036004833e81513d60248201116001600160401b038211171561271457600092505050612763565b80830180516001600160401b03811115612735576000945050505050612763565b8060208301013d860181111561275357600095505050505050612763565b601f01601f191660405250925050505b8061276e5750612817565b816001600160a01b03167ff91a8f63e5b3e0e89e5f93e1915a7805f3c52d9a73b3c09769785c2c7bf87acf826040518080602001828103825283818151815260200191508051906020019080838360005b838110156127d75781810151838201526020016127bf565b50505050905090810190601f1680156128045780820380516001836020036101000a031916815260200191505b509250505060405180910390a2506128ec565b3d808015612841576040519150601f19603f3d011682016040523d82523d6000602084013e612846565b606091505b50816001600160a01b03167f63ac299d6332d1cc4e61b81e59bc00c0ac7c798addadf33840f1307cd2977351826040518080602001828103825283818151815260200191508051906020019080838360005b838110156128b0578181015183820152602001612898565b50505050905090810190601f1680156128dd5780820380516001836020036101000a031916815260200191505b509250505060405180910390a2505b505b60ff80861660009081526009602052604090205461100591636f93d2e6918a91339187911680612920575060ff881615155b604080516001600160e01b031960e088901b1681526001600160a01b039586166004820152939094166024840152604483019190915215156064820152905160848083019260209291908290030181600087803b15801561298057600080fd5b505af1158015612994573d6000803e3d6000fd5b505050506040513d60208110156129aa57600080fd5b50505050505050505050505b5050505050505050505050505050565b630100610081565b600981565b61100781565b61100681565b60005460ff1681565b3361100714612a285760405162461bcd60e51b815260040180806020018281038252602e815260200180614908602e913960400191505060405180910390fd5b600b5460ff1615612a6c576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b612ad584848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526012815271626174636853697a65466f724f7261636c6560701b602082015291506146129050565b15612b7057604080516020601f8401819004810282018101909252828152600091612b18918585808385018382808284376000920191909152506146f992505050565b90506127108111158015612b2d5750600a8110155b612b685760405162461bcd60e51b81526004018080602001828103825260328152602001806149806032913960400191505060405180910390fd5b60015561341a565b612bd984848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601281527118591913dc955c19185d1950da185b9b995b60721b602082015291506146129050565b15612d6157606082828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505082519293505060169091149050612c5c5760405162461bcd60e51b815260040180806020018281038252605a815260200180614821605a913960600191505060405180910390fd5b60018101516002820151601683015160ff82161590612c7a816146fe565b612ccb576040805162461bcd60e51b815260206004820152601960248201527f61646472657373206973206e6f74206120636f6e747261637400000000000000604482015290519081900360640190fd5b60ff8416600081815260056020908152604080832080546001600160a01b0319166001600160a01b038716908117909155808452600683528184208585528352818420805460ff199081166001179091556009909352818420805490931687151517909255519092917f7e3b6af43092577ee20e60eaa1d9b114a7031305c895ee7dd3ffe17196d2e1e091a3505050505061341a565b612dce84848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526016815275195b98589b1953dc911a5cd8589b1950da185b9b995b60521b602082015291506146129050565b15612eff57606082828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505082519293505060029091149050612e515760405162461bcd60e51b815260040180806020018281038252604a815260200180614936604a913960600191505060405180910390fd5b600181810151600283015160ff80831660009081526005602052604090205492939192908316909114906001600160a01b03168015612ef5576001600160a01b038116600090815260066020908152604080832060ff881680855290835292819020805460ff1916861515908117909155815190815290517fa3132e3f9819fbddc7f0ed6d38d7feef59aa95112090b7c592f5cb5bc4aa4adc929181900390910190a25b505050505061341a565b612f6384848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600d81526c73757370656e6451756f72756d60981b602082015291506146129050565b156130985760028114612fa75760405162461bcd60e51b815260040180806020018281038252602d8152602001806148af602d913960400191505060405180910390fd5b6000612fea600284848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506146f992505050565b905060008161ffff16118015613004575060648161ffff16105b61304e576040805162461bcd60e51b8152602060048201526016602482015275696e76616c69642073757370656e642071756f72756d60501b604482015290519081900360640190fd5b604080516f14d554d411539117d41493d413d4d05360821b815281519081900360100190206000908152600d60205220805461ffff90921661ffff1990921691909117905561341a565b6130fb84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600c81526b72656f70656e51756f72756d60a01b602082015291506146129050565b1561322e576002811461313f5760405162461bcd60e51b815260040180806020018281038252602c8152602001806148dc602c913960400191505060405180910390fd5b6000613182600284848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506146f992505050565b905060008161ffff1611801561319c575060648161ffff16105b6131e5576040805162461bcd60e51b8152602060048201526015602482015274696e76616c69642072656f70656e2071756f72756d60581b604482015290519081900360640190fd5b604080516e149153d4115397d41493d413d4d053608a1b8152815190819003600f0190206000908152600d60205220805461ffff90921661ffff1990921691909117905561341a565b61329984848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601481527363616e63656c5472616e7366657251756f72756d60601b602082015291506146129050565b156133dd57600281146132dd5760405162461bcd60e51b815260040180806020018281038252603481526020018061487b6034913960400191505060405180910390fd5b6000613320600284848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506146f992505050565b905060008161ffff1611801561333a575060648161ffff16105b61338b576040805162461bcd60e51b815260206004820152601e60248201527f696e76616c69642063616e63656c207472616e736665722071756f72756d0000604482015290519081900360640190fd5b604080517710d05390d15317d514905394d1915497d41493d413d4d05360421b815281519081900360180190206000908152600d60205220805461ffff90921661ffff1990921691909117905561341a565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b6008602052600090815260409020546001600160401b031681565b7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081565b61100281565b60005460ff16613536576040805162461bcd60e51b815260206004820152601960248201526000805160206149b2833981519152604482015290519081900360640190fd5b6040805163569e4ed360e11b815233600482015290516000916110009163ad3c9da691602480820192602092909190829003018186803b15801561357957600080fd5b505afa15801561358d573d6000803e3d6000fd5b505050506040513d60208110156135a357600080fd5b505160408051633d42651560e11b8152905191925060009161100091637a84ca2a916004808301926020929190829003018186803b1580156135e457600080fd5b505afa1580156135f8573d6000803e3d6000fd5b505050506040513d602081101561360e57600080fd5b505190508061361b575060155b60008211801561362b5750808211155b61366a576040805162461bcd60e51b815260206004820152600b60248201526a1b9bdd0818d8589a5b995d60aa1b604482015290519081900360640190fd5b600b5460ff166136b1576040805162461bcd60e51b815260206004820152600d60248201526c1b9bdd081cdd5cdc195b991959609a1b604482015290519081900360640190fd5b604080516e149153d4115397d41493d413d4d053608a1b8152905190819003600f019020600090613702907fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4706140e3565b9050801561374057600b805460ff1916905560405133907f899fe8c37dc61708a3aaa99c4bf143346c1d1da69af79be9e8920c0a6785b75290600090a25b505050565b600660209081526000928352604080842090915290825290205460ff1681565b6040518060400160405280600381526020016269626360e81b81525081565b610e1081565b61100381565b60005460ff16156137e8576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b7f1471eb6eb2c5e789fc3de43f8ce62938c7d1836ec861730447e2ada8fd81017b80546001600160a01b0319908116611008179091557f92e85d02570a8092d09a6e3a57665bc3815a2699a4074001bf1ccabf660f5a36805460ff199081169091557fd8af288fc1c8680b4f4706064cf021e264efb6828fcaf7eb5ca36818eb365bcc8054821660019081179091557f89832631fb3c3307a103ba2c84ab569c64d6182a18893dcd163f0f1c2090733a805484166110049081179091557f6cde3cea4b3a3fb2488b2808bae7556f4a405e50f65e1794383bc026131b13c38054841690557f72e4efa1513b071517c6c74dba31b5934a81aa83cddd400e7081df5529c9943680548416831790557fa9bc9a3a348c357ba16b37005d7e6b3236198c0e939f4af8c5f19b8deeb8ebc08054851690911790557fc575c31fea594a6eb97c8e9d3f9caee4c16218c6ef37e923234c0fe9014a61e78054831690557f4e523af77f034e9810f1c94057f5e931fb3d16a51511a4c3add793617d18610580548316821790557ffb33122aa9f93cc639ebe80a7bc4784c11e6053dde89c6f4f7e268c6a623da1e805484166110001790557fc7694af312c4f286114180fd0ba6a52461fcee8a381636770b19a343af92538a80548316821790557f01112dd68e482ba8d68a7e828cff8b3abcea08eab88941953c180a7e650e9cd480548316821790557fc0a4a8be475dfebc377ebef2d7c4ff47656f572a08dd92b81017efcdba0febe1805484166110071790557f87e8a52529e8ece4ef759037313542a6429ff494a9fab9027fb79db90124eba680548316821790557f4c7666bbcb22d46469f7cc282f70764a7012dca2cce630ff8d83db9a9cdd48f080548316821790557f40f28f99a40bc9f6beea1013afdbc3cdcc689eb76b82c4de06c0acf1e1932ed58054909316611001179092557f0d9cf2cd531699eed8dd34e40ff2884a14a698c4898184fba85194e6f6772d248054821683179055600b60009081527f23f68c9bd22b8a93d06adabe17481c87c016bcbd20adc8bfd707a4d813a572176020527fdf0d5d05428057f5455c2dc8e810dd86d1e9350faa72f16bda8a45443c5b39328054831684179055603283556004805467ffffffffffffffff19166001600160401b031790556002819055600381905580549091169091179055565b6007602052600090815260409020546001600160401b031681565b60005460ff16613ba7576040805162461bcd60e51b815260206004820152601960248201526000805160206149b2833981519152604482015290519081900360640190fd5b6040805163569e4ed360e11b815233600482015290516000916110009163ad3c9da691602480820192602092909190829003018186803b158015613bea57600080fd5b505afa158015613bfe573d6000803e3d6000fd5b505050506040513d6020811015613c1457600080fd5b505160408051633d42651560e11b8152905191925060009161100091637a84ca2a916004808301926020929190829003018186803b158015613c5557600080fd5b505afa158015613c69573d6000803e3d6000fd5b505050506040513d6020811015613c7f57600080fd5b5051905080613c8c575060155b600082118015613c9c5750808211155b613cdb576040805162461bcd60e51b815260206004820152600b60248201526a1b9bdd0818d8589a5b995d60aa1b604482015290519081900360640190fd5b600b5460ff1615613d1f576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b604080516f14d554d411539117d41493d413d4d05360821b81529051908190036010019020600090613d71907fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4706140e3565b905080156137405761374061401a565b60005460ff16613dc6576040805162461bcd60e51b815260206004820152601960248201526000805160206149b2833981519152604482015290519081900360640190fd5b33600090815260066020908152604080832060ff8089168552925290912054859116613e235760405162461bcd60e51b81526004018080602001828103825260318152602001806147f06031913960400191505060405180910390fd5b60ff85166000908152600760209081526040808320548151601f88018490048402810184019092528682526001600160401b031692613e889284928a9261208d92909189918c908c908190840183828082843760009201919091525061131c92505050565b60ff959095166000908152600760205260409020805467ffffffffffffffff191660019096016001600160401b03169590951790945550505050565b61100081565b600381565b61100481565b60408051600e808252818301909252606091630100610060ff851617918391602082018180368337505050600e81810187905260068201939093529182525090505b92915050565b600085613f2c57506000614011565b606082518451865160800101016040519080825280601f01601f191660200182016040528015613f63576020820181803683370190505b5090506000613f7182614704565b602080890151825201905086600080613f8989614098565b8086526020909501949092509050613fa28285836140a2565b92830192613faf88614098565b8086526020909501949092509050613fc88285836140a2565b9283018a815260200192613fdb87614098565b9092509050613feb8285836140a2565b508351602001613ff961470a565b60208183886065600019fa5051600114955050505050505b95945050505050565b600b5460ff161561405e576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b600b805460ff1916600117905560405133907f6f123d3d54c84a7960a573b31c221dcd86e13fd849c5adb0c6ca851468cc1ae490600090a2565b8051602090910191565b5b602081106140c2578251825260209283019290910190601f19016140a3565b915181516020939093036101000a6000190180199091169216919091179052565b6000828152600d602052604081205461ffff166141ac57604080516f14d554d411539117d41493d413d4d05360821b815281519081900360100181206000908152600d6020818152848320805461ffff199081166001179091556e149153d4115397d41493d413d4d053608a1b8552855194859003600f01852084528282528584208054821660029081179091557710d05390d15317d514905394d1915497d41493d413d4d05360421b8652865195869003601801909520845291905292902080549092161790555b6000838152600c6020526040902080546201000090046001600160801b0316421015806141dd575082816001015414155b156142b0576000848152600d602090815260409182902054835461ffff90911661ffff199091161771ffffffffffffffffffffffffffffffff0000191662010000610e1042016001600160801b0316021783556001808401869055825191820190925233815261425291600284019190614728565b5080546040805161ffff83168152620100009092046001600160801b0316602083015281810185905251339186917f9e109f0e55ef32e99e4880be2ec357f1ddb3469c79d0747ef4762da6e89fabe5916060908290030190a3614364565b60005b600282015481101561433b57336001600160a01b03168260020182815481106142d857fe5b6000918252602090912001546001600160a01b03161415614333576040805162461bcd60e51b815260206004820152601060248201526f185b1c9958591e48185c1c1c9bdd995960821b604482015290519081900360640190fd5b6001016142b3565b50600281018054600181018255600091825260209091200180546001600160a01b031916331790555b8054600282015461ffff909116116143be576000848152600c60205260408120805471ffffffffffffffffffffffffffffffffffff1916815560018101829055906143b2600283018261478d565b50506001915050613f17565b5060009392505050565b600080600060606021855110156143f8575050604080516000808252602082019092529092508291508190614471565b600185015160218601518651604080516020198301808252601f1960011990940193909316810160200190915260418901939291606091908015614443576020820181803683370190505b509050600061445182614098565b509050614463858260218d51036140a2565b506001975091955093509150505b9193509193565b600b5460ff16156144bc576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b6002544311156144fb576004805467ffffffffffffffff1981166001600160401b036001600793840b810190930b16179091556003554360025561453c565b6003805460019081019182905554101561453c576004805467ffffffffffffffff1981166001600160401b036001600793840b810190930b16179091556003555b8160ff16836001600160401b0316600460009054906101000a900460070b6001600160401b03167f3a6e0fc61675aa2a100bcba0568368bb92bcec91c97673391074f11138f0cffe606185604051808361ffff1661ffff16815260200180602001828103825283818151815260200191508051906020019080838360005b838110156145d25781810151838201526020016145ba565b50505050905090810190601f1680156145ff5780820380516001836020036101000a031916815260200191505b50935050505060405180910390a4505050565b6000816040516020018082805190602001908083835b602083106146475780518252601f199092019160209182019101614628565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b602083106146b55780518252601f199092019160209182019101614696565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b015190565b3b151590565b60200190565b60405180602001604052806001906020820280368337509192915050565b82805482825590600052602060002090810192821561477d579160200282015b8281111561477d57825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190614748565b506147899291506147ae565b5090565b50805460008255906000526020600020908101906147ab91906147d5565b50565b6147d291905b808211156147895780546001600160a01b03191681556001016147b4565b90565b6147d291905b8082111561478957600081556001016147db56fe74686520636f6e747261637420616e64206368616e6e656c2068617665206e6f74206265656e20726567697374657265646c656e677468206f662076616c756520666f72206164644f725570646174654368616e6e656c2073686f756c642062652032322c206368616e6e656c49643a697346726f6d53797374656d3a68616e646c6572416464726573736c656e677468206f662076616c756520666f722063616e63656c5472616e7366657251756f72756d2073686f756c6420626520326c656e677468206f662076616c756520666f722073757370656e6451756f72756d2073686f756c6420626520326c656e677468206f662076616c756520666f722072656f70656e51756f72756d2073686f756c642062652032746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e74726163746c656e677468206f662076616c756520666f7220656e61626c654f7244697361626c654368616e6e656c2073686f756c6420626520322c206368616e6e656c49643a6973456e61626c65746865206e6577426174636853697a65466f724f7261636c652073686f756c6420626520696e205b31302c2031303030305d74686520636f6e7472616374206e6f7420696e697420796574000000000000006c6967687420636c69656e74206e6f742073796e632074686520626c6f636b20796574a26469706673582212200822a3bd79df610f758cc9702e0be636463b002fc0089f5e09cf86383a7f79fc64736f6c63430006040033", + }, + }, + } + + lubanUpgrade[rialtoNet] = &Upgrade{ + UpgradeName: "luban", + Configs: []*UpgradeConfig{ + { + ContractAddr: common.HexToAddress(ValidatorContract), + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/b144718e94d7a1ebb24a7103202300f08826f369", + Code: "60806040526004361061046c5760003560e01c8063862498821161024a578063c6d3394511610139578063e40716a1116100b6578063f9a2bbc71161007a578063f9a2bbc714610b6b578063fc3e590814610b80578063fccc281314610b95578063fd4ad81f14610baa578063fd6a687914610bd957610473565b8063e40716a114610af9578063eb57e20214610b0e578063eda5868c14610b2e578063f340fa0114610b43578063f92eb86b14610b5657610473565b8063d86222d5116100fd578063d86222d514610a90578063daacdb6614610aa5578063dc927faf14610aba578063e086c7b114610acf578063e1c7392a14610ae457610473565b8063c6d3394514610a3c578063c81b166214610a51578063c8509d811461085f578063d04aa99614610a66578063d68fb56a14610a7b57610473565b8063a5422d5c116101c7578063ad3c9da61161018b578063ad3c9da6146109d0578063aef198a9146109f0578063b7ab4db514610a05578063b8cf4ef114610a27578063bf9f49951461062f57610473565b8063a5422d5c1461095c578063a78abc1614610971578063aaf5eb6814610986578063ab51bb961461099b578063ac431751146109b057610473565b806396713da91161020e57806396713da9146108f35780639dc09262146109085780639fe0f8161461091d578063a0dc275814610932578063a1a11bf51461094757610473565b8063862498821461087f57806388b32f11146108945780638b5ad0c9146108a95780638d19a410146108be5780639369d7de146108de57610473565b80634df6e0c3116103665780636e47b482116102e35780637942fd05116102a75780637942fd05146108205780637a84ca2a1461083557806381650b621461084a578063831d65d11461085f578063853230aa1461080b57610473565b80636e47b482146107b757806370fd5bad146107cc578063718a8aa8146107e157806375d47a0a146107f657806378dfed4a1461080b57610473565b8063565c56b31161032a578063565c56b3146107265780635667515a146107465780635d77156c1461075b57806362b72cf5146107705780636969a25c1461078557610473565b80634df6e0c3146106b25780635192c82c146106c757806351e80672146106dc578063549b03f2146106f157806355614fcc1461070657610473565b8063321d398a116103f45780633dffc387116103b85780633dffc3871461062f57806343756e5c1461065157806345cf9daf14610666578063493279b11461067b5780634bf6c8821461069d57610473565b8063321d398a146105975780633365af3a146105b757806335409f7f146105d75780633b071dcc146105f75780633de0f0d81461061a57610473565b80631182b8751161043b5780631182b875146104fe578063152ad3b81461052b5780631ff180691461054d578063219f22d514610562578063300c35671461057757610473565b806304c4fec61461047857806307a568471461048f5780630bee7a67146104ba5780630e2374a5146104dc57610473565b3661047357005b600080fd5b34801561048457600080fd5b5061048d610bee565b005b34801561049b57600080fd5b506104a4610c60565b6040516104b19190616ef1565b60405180910390f35b3480156104c657600080fd5b506104cf610c66565b6040516104b19190616f1b565b3480156104e857600080fd5b506104f1610c6b565b6040516104b191906162f8565b34801561050a57600080fd5b5061051e6105193660046161de565b610c71565b6040516104b1919061646f565b34801561053757600080fd5b50610540610ea9565b6040516104b19190616464565b34801561055957600080fd5b506104a4610eb2565b34801561056e57600080fd5b506104cf610eb8565b34801561058357600080fd5b5061048d6105923660046160a7565b610ebd565b3480156105a357600080fd5b506105406105b236600461618b565b611241565b3480156105c357600080fd5b506105406105d236600461618b565b611310565b3480156105e357600080fd5b5061048d6105f2366004616080565b6113c1565b34801561060357600080fd5b5061060c61151a565b6040516104b192919061637a565b34801561062657600080fd5b506104a46117f6565b34801561063b57600080fd5b506106446117fc565b6040516104b19190616f2c565b34801561065d57600080fd5b506104f1611801565b34801561067257600080fd5b506104a4611807565b34801561068757600080fd5b5061069061180d565b6040516104b19190616ee2565b3480156106a957600080fd5b50610644611813565b3480156106be57600080fd5b5061060c611818565b3480156106d357600080fd5b506104a4611996565b3480156106e857600080fd5b506104f161199c565b3480156106fd57600080fd5b506104a46119a2565b34801561071257600080fd5b50610540610721366004616080565b6119a8565b34801561073257600080fd5b506104a4610741366004616080565b6119dd565b34801561075257600080fd5b50610644611a2e565b34801561076757600080fd5b506104cf611a33565b34801561077c57600080fd5b506104a4611a38565b34801561079157600080fd5b506107a56107a036600461618b565b611a3e565b6040516104b196959493929190616325565b3480156107c357600080fd5b506104f1611aa2565b3480156107d857600080fd5b50610644611aa8565b3480156107ed57600080fd5b50610644611aad565b34801561080257600080fd5b506104f1611ab2565b34801561081757600080fd5b506104a4611ab8565b34801561082c57600080fd5b50610644611abe565b34801561084157600080fd5b506104a4611ac3565b34801561085657600080fd5b506104cf611ac9565b34801561086b57600080fd5b5061048d61087a3660046161de565b611ace565b34801561088b57600080fd5b506104a4611b2f565b3480156108a057600080fd5b506104a4611b35565b3480156108b557600080fd5b506104a4611b3b565b3480156108ca57600080fd5b506104a46108d9366004616080565b611b41565b3480156108ea57600080fd5b5061048d611b81565b3480156108ff57600080fd5b50610644611c95565b34801561091457600080fd5b506104f1611c9a565b34801561092957600080fd5b506104a4611ca0565b34801561093e57600080fd5b506104a4611ca5565b34801561095357600080fd5b506104f1611caa565b34801561096857600080fd5b5061051e611cb0565b34801561097d57600080fd5b50610540611ccf565b34801561099257600080fd5b506104a4611cd8565b3480156109a757600080fd5b506104cf611a2e565b3480156109bc57600080fd5b5061048d6109cb36600461612f565b611ce1565b3480156109dc57600080fd5b506104a46109eb366004616080565b61258d565b3480156109fc57600080fd5b506104a461259f565b348015610a1157600080fd5b50610a1a6125ac565b6040516104b19190616367565b348015610a3357600080fd5b506104a4612698565b348015610a4857600080fd5b506104a4611aa8565b348015610a5d57600080fd5b506104f161269d565b348015610a7257600080fd5b506104a46126a3565b348015610a8757600080fd5b506104a46126a8565b348015610a9c57600080fd5b506104a46126e7565b348015610ab157600080fd5b506104a46126f3565b348015610ac657600080fd5b506104f16126f9565b348015610adb57600080fd5b506104a46126ff565b348015610af057600080fd5b5061048d612704565b348015610b0557600080fd5b506104a46128b3565b348015610b1a57600080fd5b5061048d610b29366004616080565b6128b9565b348015610b3a57600080fd5b506104cf6129c1565b61048d610b51366004616080565b6129c6565b348015610b6257600080fd5b506104a4612c4e565b348015610b7757600080fd5b506104f1612c54565b348015610b8c57600080fd5b50610644611ca0565b348015610ba157600080fd5b506104f1612c5a565b348015610bb657600080fd5b50610bca610bc536600461618b565b612c60565b6040516104b193929190616efa565b348015610be557600080fd5b506104f1612d22565b6000610bf933611b41565b9050600b8181548110610c0857fe5b600091825260209091206001601690920201015460ff16610c445760405162461bcd60e51b8152600401610c3b90616b9a565b60405180910390fd5b6000610c4e6126a8565b9050610c5b338383612d28565b505050565b60095481565b606481565b61200181565b60005460609060ff16610c965760405162461bcd60e51b8152600401610c3b9061662e565b3361200014610cb75760405162461bcd60e51b8152600401610c3b90616d79565b600b54610d7557610cc6615d6c565b60015460005b81811015610d7157600b8054600181018255600091909152835160008051602061714f833981519152601690920291820190815560208086015160008051602061718f8339815191528401805460ff1916911515919091179055604086015180518794610d4d9360008051602061716f833981519152909101920190615d9b565b506060820151610d639060038301906013615e15565b505050806001019050610ccc565b5050505b610d7d615e42565b6000610dbe85858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612f1492505050565b9150915080610dda57610dd160646130d0565b92505050610ea2565b815160009060ff16610dff57610df883602001518460400151613131565b9050610e6e565b825160ff1660011415610e6a57826020015151600114610e445760008051602061712f833981519152604051610e3490616a81565b60405180910390a1506067610e65565b610df88360200151600081518110610e5857fe5b6020026020010151613d85565b610e6e565b5060655b63ffffffff8116610e935750506040805160008152602081019091529150610ea29050565b610e9c816130d0565b93505050505b9392505050565b60075460ff1681565b60035481565b606881565b334114610edc5760405162461bcd60e51b8152600401610c3b90616dc8565b6010544311610efd5760405162461bcd60e51b8152600401610c3b9061678a565b60005460ff16610f1f5760405162461bcd60e51b8152600401610c3b9061662e565b600f54610f37576032600f5561100231601155611237565b60006110023168056bc75e2d63100000811115610f6657610f5f81606463ffffffff613efc16565b9150610faf565b601154811115610fa857610f5f6064610f9c600f54610f9060115486613f3e90919063ffffffff16565b9063ffffffff613f8016565b9063ffffffff613efc16565b5050611237565b6040516309a99b4f60e41b815261100290639a99b4f090610fd6903090869060040161630c565b602060405180830381600087803b158015610ff057600080fd5b505af1158015611004573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061102891906161a3565b6110023160115591508161103d575050611237565b6000805b8481101561106b5785858281811061105557fe5b9050602002013582019150806001019050611041565b508061107957505050611237565b6000806000805b8981101561122f578489898381811061109557fe5b905060200201358802816110a557fe5b0493508a8a828181106110b457fe5b90506020020160208101906110c99190616080565b6001600160a01b038116600090815260046020526040902054909350915081156111e55760006001808403815481106110fe57fe5b9060005260206000209060040201905080600201601c9054906101000a900460ff161561116b57836001600160a01b03167fb9c75cbbfde137c4281689580799ef5f52144e78858f776a5979b2b212137d858660405161115e9190616ef1565b60405180910390a26111df565b60035461117e908663ffffffff613fba16565b6003908155810154611196908663ffffffff613fba16565b60038201556040516001600160a01b038516907fcb0aad6cf9cd03bdf6137e359f541c42f38b39f007cae8e89e88aa7d8c6617b2906111d6908890616ef1565b60405180910390a25b50611227565b826001600160a01b03167fb9c75cbbfde137c4281689580799ef5f52144e78858f776a5979b2b212137d858560405161121e9190616ef1565b60405180910390a25b600101611080565b505050505050505b5050436010555050565b60015460009082106112555750600061130b565b60006001600160a01b03166001838154811061126d57fe5b60009182526020909120600490910201546001600160a01b0316148061129d5750600854158061129d5750600a54155b806112ac575060085460095410155b806112bd57506112bb82611310565b155b806112e657506000600b83815481106112d257fe5b906000526020600020906016020160000154115b806112fa575060016112f66125ac565b5111155b156113075750600061130b565b5060015b919050565b60015460009082106113245750600061130b565b600b548210611361576001828154811061133a57fe5b9060005260206000209060040201600201601c9054906101000a900460ff1615905061130b565b6001828154811061136e57fe5b9060005260206000209060040201600201601c9054906101000a900460ff161580156113bb5750600b82815481106113a257fe5b600091825260209091206001601690920201015460ff16155b92915050565b33611001146113e25760405162461bcd60e51b8152600401610c3b90616e99565b600b546114a0576113f1615d6c565b60015460005b8181101561149c57600b8054600181018255600091909152835160008051602061714f833981519152601690920291820190815560208086015160008051602061718f8339815191528401805460ff19169115159190911790556040860151805187946114789360008051602061716f833981519152909101920190615d9b565b50606082015161148e9060038301906013615e15565b5050508060010190506113f7565b5050505b6001600160a01b038116600090815260046020526040902054806114c45750611517565b6001810390506000600b82815481106114d957fe5b600091825260209091206001601690920201015460ff1690506114fc8383613fdf565b80156115055750805b15610c5b576009805460001901905550505b50565b60015460609081906000805b8281101561156d576001818154811061153b57fe5b9060005260206000209060040201600201601c9054906101000a900460ff16611565576001909101905b600101611526565b5060608160405190808252806020026020018201604052801561159a578160200160208202803683370190505b5090506060826040519080825280602002602001820160405280156115d357816020015b60608152602001906001900390816115be5790505b50600b546000945090915084141561174e5760005b8481101561174857600181815481106115fd57fe5b9060005260206000209060040201600201601c9054906101000a900460ff16611740576001818154811061162d57fe5b600091825260209091206004909102015483516001600160a01b039091169084908690811061165857fe5b60200260200101906001600160a01b031690816001600160a01b031681525050600b818154811061168557fe5b600091825260209182902060026016909202018101805460408051601f60001961010060018616150201909316949094049182018590048502840185019052808352919290919083018282801561171d5780601f106116f25761010080835404028352916020019161171d565b820191906000526020600020905b81548152906001019060200180831161170057829003601f168201915b505050505082858151811061172e57fe5b60209081029190910101526001909301925b6001016115e8565b506117ea565b60005b848110156117e8576001818154811061176657fe5b9060005260206000209060040201600201601c9054906101000a900460ff166117e0576001818154811061179657fe5b600091825260209091206004909102015483516001600160a01b03909116908490869081106117c157fe5b6001600160a01b03909216602092830291909101909101526001909301925b600101611751565b505b909450925050505b9091565b61271081565b600181565b61100181565b60085481565b6102ca81565b600881565b600e54600c5460609182918061182c575060155b60606118366125ac565b9050606061184382614392565b90508282511161185a5790945092506117f2915050565b8383835103101561186c578282510393505b83156118a25760c8430461188883838388880360008a8a614500565b6118a08383838888038989038a8b8b8b510301614500565b505b6060836040519080825280602002602001820160405280156118ce578160200160208202803683370190505b50905060608460405190808252806020026020018201604052801561190757816020015b60608152602001906001900390816118f25790505b50905060005b858110156119885784818151811061192157fe5b602002602001015183828151811061193557fe5b60200260200101906001600160a01b031690816001600160a01b03168152505083818151811061196157fe5b602002602001015182828151811061197557fe5b602090810291909101015260010161190d565b509096509450505050509091565b60065481565b61200081565b600f5481565b6001600160a01b038116600090815260046020526040812054806119d057600091505061130b565b60001901610ea281611310565b6001600160a01b03811660009081526004602052604081205480611a0557600091505061130b565b600180820381548110611a1457fe5b906000526020600020906004020160030154915050919050565b600081565b606781565b60105481565b60018181548110611a4b57fe5b600091825260209091206004909102018054600182015460028301546003909301546001600160a01b0392831694509082169291821691600160a01b81046001600160401b031691600160e01b90910460ff169086565b61100581565b600281565b601081565b61100881565b6103e881565b600b81565b600c5481565b606681565b3361200014611aef5760405162461bcd60e51b8152600401610c3b90616d79565b7f41ce201247b6ceb957dcdb217d0b8acb50b9ea0e12af9af4f5e7f38902101605838383604051611b2293929190616f3a565b60405180910390a1505050565b60025481565b60115481565b600a5481565b6001600160a01b03811660009081526004602052604081205480611b775760405162461bcd60e51b8152600401610c3b90616d01565b6000190192915050565b600b54611c3f57611b90615d6c565b60015460005b81811015611c3b57600b8054600181018255600091909152835160008051602061714f833981519152601690920291820190815560208086015160008051602061718f8339815191528401805460ff1916911515919091179055604086015180518794611c179360008051602061716f833981519152909101920190615d9b565b506060820151611c2d9060038301906013615e15565b505050806001019050611b96565b5050505b600854611c4c5760036008555b600a54611c59576002600a555b6000611c6433611b41565b9050611c6f81611241565b611c8b5760405162461bcd60e51b8152600401610c3b90616a3e565b6115173382614657565b600981565b61100781565b600381565b60c881565b61100681565b604051806101e001604052806101ab8152602001616f846101ab913981565b60005460ff1681565b6402540be40081565b60005460ff16611d035760405162461bcd60e51b8152600401610c3b9061662e565b3361100714611d245760405162461bcd60e51b8152600401610c3b90616b07565b611d8e84848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526013815272065787069726554696d655365636f6e6447617606c1b602082015291506146ef9050565b15611e2b5760208114611db35760405162461bcd60e51b8152600401610c3b90616cbb565b604080516020601f8401819004810282018101909252828152600091611df19185858083850183828082843760009201919091525061474892505050565b905060648110158015611e075750620186a08111155b611e235760405162461bcd60e51b8152600401610c3b906168e7565b60025561254a565b611e8b84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260098152686275726e526174696f60b81b602082015291506146ef9050565b15611f275760208114611eb05760405162461bcd60e51b8152600401610c3b906164b4565b604080516020601f8401819004810282018101909252828152600091611eee9185858083850183828082843760009201919091525061474892505050565b9050612710811115611f125760405162461bcd60e51b8152600401610c3b906167cc565b6006556007805460ff1916600117905561254a565b611f9184848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260138152726d61784e756d4f664d61696e7461696e696e6760681b602082015291506146ef9050565b1561202b5760208114611fb65760405162461bcd60e51b8152600401610c3b906164eb565b604080516020601f8401819004810282018101909252828152600091611ff49185858083850183828082843760009201919091525061474892505050565b600c5490915080612003575060155b8082106120225760405162461bcd60e51b8152600401610c3b9061683f565b5060085561254a565b61209484848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260128152716d61696e7461696e536c6173685363616c6560701b602082015291506146ef9050565b1561212d57602081146120b95760405162461bcd60e51b8152600401610c3b906165b4565b604080516020601f84018190048102820181019092528281526000916120f79185858083850183828082843760009201919091525061474892505050565b90506000811180156121095750600a81105b6121255760405162461bcd60e51b8152600401610c3b90616e15565b600a5561254a565b6121a184848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601981527f6d61784e756d4f66576f726b696e6743616e6469646174657300000000000000602082015291506146ef9050565b1561223057602081146121c65760405162461bcd60e51b8152600401610c3b90616568565b604080516020601f84018190048102820181019092528281526000916122049185858083850183828082843760009201919091525061474892505050565b9050600d548111156122285760405162461bcd60e51b8152600401610c3b9061695d565b600e5561254a565b61229984848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260128152716d61784e756d4f6643616e6469646174657360701b602082015291506146ef9050565b1561231b57602081146122be5760405162461bcd60e51b8152600401610c3b90616b55565b604080516020601f84018190048102820181019092528281526000916122fc9185858083850183828082843760009201919091525061474892505050565b600d819055600e5490915081101561231557600d54600e555b5061254a565b61237f84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600d81526c6e756d4f66436162696e65747360981b602082015291506146ef9050565b1561242d57602081146123a45760405162461bcd60e51b8152600401610c3b906165f9565b604080516020601f84018190048102820181019092528281526000916123e29185858083850183828082843760009201919091525061474892505050565b9050600081116124045760405162461bcd60e51b8152600401610c3b9061669c565b60298111156124255760405162461bcd60e51b8152600401610c3b906166e4565b600c5561254a565b61249784848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601381527266696e616c697479526577617264526174696f60681b602082015291506146ef9050565b1561253257602081146124bc5760405162461bcd60e51b8152600401610c3b90616c3e565b604080516020601f84018190048102820181019092528281526000916124fa9185858083850183828082843760009201919091525061474892505050565b90506001811015801561250e575060648111155b61252a5760405162461bcd60e51b8152600401610c3b906169cc565b600f5561254a565b60405162461bcd60e51b8152600401610c3b90616e72565b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a8484848460405161257f9493929190616482565b60405180910390a150505050565b60046020526000908152604090205481565b68056bc75e2d6310000081565b6001546060906000805b828110156125db576125c781611310565b156125d3578160010191505b6001016125b6565b50606081604051908082528060200260200182016040528015612608578160200160208202803683370190505b5090506000915060005b8381101561268f5761262381611310565b15612687576001818154811061263557fe5b600091825260209091206004909102015482516001600160a01b039091169083908590811061266057fe5b60200260200101906001600160a01b031690816001600160a01b0316815250508260010192505b600101612612565b50925050505b90565b601581565b61100281565b603281565b60006126b26125ac565b519050600080600c54116126c75760156126cb565b600c545b9050808211156126d9578091505b816126e357600191505b5090565b67016345785d8a000081565b60055481565b61100381565b602981565b60005460ff16156127275760405162461bcd60e51b8152600401610c3b90616c07565b61272f615e42565b6000612755604051806101e001604052806101ab8152602001616f846101ab9139612f14565b91509150806127765760405162461bcd60e51b8152600401610c3b90616d38565b60005b82602001515181101561289b5760018360200151828151811061279857fe5b60209081029190910181015182546001818101855560009485528385208351600493840290910180546001600160a01b039283166001600160a01b03199182161782558587015182850180549185169183169190911790556040860151600283018054606089015160808a01511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b199590981692909516919091179290921694909417161790915560a09093015160039093019290925591860151805191850193918590811061286e57fe5b602090810291909101810151516001600160a01b0316825281019190915260400160002055600101612779565b50506103e8600255506000805460ff19166001179055565b600d5481565b33611001146128da5760405162461bcd60e51b8152600401610c3b90616e99565b600b54612998576128e9615d6c565b60015460005b8181101561299457600b8054600181018255600091909152835160008051602061714f833981519152601690920291820190815560208086015160008051602061718f8339815191528401805460ff19169115159190911790556040860151805187946129709360008051602061716f833981519152909101920190615d9b565b5060608201516129869060038301906013615e15565b5050508060010190506128ef565b5050505b60006129a38261474d565b90506129ae81611241565b156129bd576129bd8282614657565b5050565b606581565b3341146129e55760405162461bcd60e51b8152600401610c3b90616dc8565b60005460ff16612a075760405162461bcd60e51b8152600401610c3b9061662e565b60003411612a275760405162461bcd60e51b8152600401610c3b9061692e565b6001600160a01b0381166000908152600460205260409020546007543491906103e89060ff1615612a5757506006545b600083118015612a675750600081115b15612b08576000612a84612710610f9c868563ffffffff613f8016565b90508015612b065760405161dead9082156108fc029083906000818181858888f19350505050158015612abb573d6000803e3d6000fd5b507f627059660ea01c4733a328effb2294d2f86905bf806da763a89cee254de8bee581604051612aeb9190616ef1565b60405180910390a1612b03848263ffffffff613f3e16565b93505b505b8115612c06576000600180840381548110612b1f57fe5b9060005260206000209060040201905080600201601c9054906101000a900460ff1615612b8c57846001600160a01b03167ff177e5d6c5764d79c32883ed824111d9b13f5668cf6ab1cc12dd36791dd955b485604051612b7f9190616ef1565b60405180910390a2612c00565b600354612b9f908563ffffffff613fba16565b6003908155810154612bb7908563ffffffff613fba16565b60038201556040516001600160a01b038616907f93a090ecc682c002995fad3c85b30c5651d7fd29b0be5da9d784a3302aedc05590612bf7908790616ef1565b60405180910390a25b50612c48565b836001600160a01b03167ff177e5d6c5764d79c32883ed824111d9b13f5668cf6ab1cc12dd36791dd955b484604051612c3f9190616ef1565b60405180910390a25b50505050565b600e5481565b61100081565b61dead81565b600b8181548110612c6d57fe5b6000918252602091829020601691909102018054600180830154600280850180546040805161010096831615969096026000190190911692909204601f810188900488028501880190925281845293965060ff90911694919291830182828015612d185780601f10612ced57610100808354040283529160200191612d18565b820191906000526020600020905b815481529060010190602001808311612cfb57829003601f168201915b5050505050905083565b61100481565b6000600a5460001480612d39575081155b80612d445750600954155b15612d5157506000610ea2565b60096000815460019003919050819055506000612d9c600a54610f9c85610f9c600b8981548110612d7e57fe5b6000918252602090912060169091020154439063ffffffff613f3e16565b90506000600b8581548110612dad57fe5b906000526020600020906016020160010160006101000a81548160ff0219169083151502179055506000806110016001600160a01b0316638256ace66040518163ffffffff1660e01b8152600401604080518083038186803b158015612e1257600080fd5b505afa158015612e26573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e4a91906161bb565b9150915060009350808310612ec457612e638787613fdf565b506040516305bfb49960e41b815261100190635bfb499090612e89908a906004016162f8565b600060405180830381600087803b158015612ea357600080fd5b505af1158015612eb7573d6000803e3d6000fd5b5050505060019350612ed6565b818310612ed657612ed48761474d565b505b6040516001600160a01b038816907fb9d38178dc641ff1817967a63c9078cbcd955a9f1fcd75e0e3636de615d44d3b90600090a25050509392505050565b612f1c615e42565b6000612f26615e42565b612f2e615e66565b612f3f612f3a866148f0565b614915565b90506000805b612f4e8361495f565b156130c25780612f7357612f69612f6484614980565b6149ce565b60ff1684526130ba565b80600114156130b5576060612f8f612f8a85614980565b614a4e565b90508051604051908082528060200260200182016040528015612fcc57816020015b612fb9615e86565b815260200190600190039081612fb15790505b508560200181905250805160405190808252806020026020018201604052801561300a57816020015b6060815260200190600190039081612ff55790505b50604086015260005b81518110156130aa57613024615e86565b6060600061304485858151811061303757fe5b6020026020010151614b1f565b92509250925080613064578860009a509a505050505050505050506130cb565b828960200151858151811061307557fe5b6020026020010181905250818960400151858151811061309157fe5b6020026020010181905250505050806001019050613013565b5060019250506130ba565b6130c2565b600101612f45565b50919350909150505b915091565b604080516001808252818301909252606091829190816020015b60608152602001906001900390816130ea5790505090506131108363ffffffff16614c39565b8160008151811061311d57fe5b6020026020010181905250610ea281614c4c565b60006029835111156131685760008051602061712f83398151915260405161315890616741565b60405180910390a15060666113bb565b60005b83518110156132065760005b818110156131fd5784818151811061318b57fe5b6020026020010151600001516001600160a01b03168583815181106131ac57fe5b6020026020010151600001516001600160a01b031614156131f55760008051602061712f8339815191526040516131e29061689c565b60405180910390a16066925050506113bb565b600101613177565b5060010161316b565b506060806132148585614cd6565b60015491935091506000908190815b818110156132995767016345785d8a00006001828154811061324157fe5b9060005260206000209060040201600301541061326357836001019350613291565b60006001828154811061327257fe5b9060005260206000209060040201600301541115613291578260010192505b600101613223565b506060836040519080825280602002602001820160405280156132c6578160200160208202803683370190505b5090506060846040519080825280602002602001820160405280156132f5578160200160208202803683370190505b509050606085604051908082528060200260200182016040528015613324578160200160208202803683370190505b509050606086604051908082528060200260200182016040528015613353578160200160208202803683370190505b5090506000606087604051908082528060200260200182016040528015613384578160200160208202803683370190505b5090506060886040519080825280602002602001820160405280156133b3578160200160208202803683370190505b509050600099506000985060006110046001600160a01b031663149d14d96040518163ffffffff1660e01b815260040160206040518083038186803b1580156133fb57600080fd5b505afa15801561340f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061343391906161a3565b905067016345785d8a000081111561347e5760008051602061712f83398151915260405161346090616bc6565b60405180910390a160689d50505050505050505050505050506113bb565b60005b898110156136ef5767016345785d8a00006001828154811061349f57fe5b9060005260206000209060040201600301541061362457600181815481106134c357fe5b906000526020600020906004020160020160009054906101000a90046001600160a01b0316898d815181106134f457fe5b60200260200101906001600160a01b031690816001600160a01b03168152505060006402540be4006001838154811061352957fe5b9060005260206000209060040201600301548161354257fe5b066001838154811061355057fe5b9060005260206000209060040201600301540390506135788382613f3e90919063ffffffff16565b898e8151811061358457fe5b6020026020010181815250506001828154811061359d57fe5b906000526020600020906004020160020160009054906101000a90046001600160a01b0316878e815181106135ce57fe5b60200260200101906001600160a01b031690816001600160a01b03168152505081888e815181106135fb57fe5b6020908102919091010152613616868263ffffffff613fba16565b95508c6001019c50506136e7565b60006001828154811061363357fe5b90600052602060002090600402016003015411156136e7576001818154811061365857fe5b906000526020600020906004020160010160009054906101000a90046001600160a01b0316848c8151811061368957fe5b60200260200101906001600160a01b031690816001600160a01b031681525050600181815481106136b657fe5b906000526020600020906004020160030154838c815181106136d457fe5b6020026020010181815250508a6001019a505b600101613481565b5060008415613965576002546040516303702b2960e51b815261100491636e056520918891613729918e918e918d914201906004016163ea565b6020604051808303818588803b15801561374257600080fd5b505af193505050508015613773575060408051601f3d908101601f191682019092526137709181019061610f565b60015b6138ea576040516000815260443d101561378f5750600061382a565b60046000803e60005160e01c6308c379a081146137b057600091505061382a565b60043d036004833e81513d60248201116001600160401b03821117156137db5760009250505061382a565b80830180516001600160401b038111156137fc57600094505050505061382a565b8060208301013d860181111561381a5760009550505050505061382a565b601f01601f191660405250925050505b806138355750613877565b60019150857fa7cdeed7d0db45e3219a6e5d60838824c16f1d39991fcfe3f963029c844bf28082604051613869919061646f565b60405180910390a2506138e5565b3d8080156138a1576040519150601f19603f3d011682016040523d82523d6000602084013e6138a6565b606091505b5060019150857fbfa884552dd8921b6ce90bfe906952ae5b3b29be0cc1a951d4f62697635a3a45826040516138db919061646f565b60405180910390a2505b613965565b801561392c577fa217d08e65f80c73121cd9db834d81652d544bfbf452f6d04922b16c90a37b708660405161391f9190616ef1565b60405180910390a1613963565b857fa7cdeed7d0db45e3219a6e5d60838824c16f1d39991fcfe3f963029c844bf28060405161395a90616531565b60405180910390a25b505b8015613b1b5760005b8751811015613b1957600088828151811061398557fe5b6020026020010151905060006001828154811061399e57fe5b60009182526020909120600160049092020181015481546001600160a01b03909116916108fc91859081106139cf57fe5b9060005260206000209060040201600301549081150290604051600060405180830381858888f1935050505090508015613a8b5760018281548110613a1057fe5b60009182526020909120600160049092020181015481546001600160a01b03909116917f6c61d60f69a7beb3e1c80db7f39f37b208537cbb19da3174511b477812b2fc7d9185908110613a5f57fe5b906000526020600020906004020160030154604051613a7e9190616ef1565b60405180910390a2613b0f565b60018281548110613a9857fe5b60009182526020909120600160049092020181015481546001600160a01b03909116917f25d0ce7d2f0cec669a8c17efe49d195c13455bb8872b65fa610ac7f53fe4ca7d9185908110613ae757fe5b906000526020600020906004020160030154604051613b069190616ef1565b60405180910390a25b505060010161396e565b505b835115613c655760005b8451811015613c63576000858281518110613b3c57fe5b60200260200101516001600160a01b03166108fc868481518110613b5c57fe5b60200260200101519081150290604051600060405180830381858888f1935050505090508015613bf257858281518110613b9257fe5b60200260200101516001600160a01b03167f6c61d60f69a7beb3e1c80db7f39f37b208537cbb19da3174511b477812b2fc7d868481518110613bd057fe5b6020026020010151604051613be59190616ef1565b60405180910390a2613c5a565b858281518110613bfe57fe5b60200260200101516001600160a01b03167f25d0ce7d2f0cec669a8c17efe49d195c13455bb8872b65fa610ac7f53fe4ca7d868481518110613c3c57fe5b6020026020010151604051613c519190616ef1565b60405180910390a25b50600101613b25565b505b5050505050505050505050506000471115613ce1577f6ecc855f9440a9282c90913bbc91619fd44f5ec0b462af28d127b116f130aa4d47604051613ca99190616ef1565b60405180910390a1604051611002904780156108fc02916000818181858888f19350505050158015613cdf573d6000803e3d6000fd5b505b60006003819055600555815115613cfc57613cfc8282614f0f565b6110016001600160a01b031663fc4333cd6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015613d3957600080fd5b505af1158015613d4d573d6000803e3d6000fd5b50506040517fedd8d7296956dd970ab4de3f2fc03be2b0ffc615d20cd4c72c6e44f928630ebf925060009150a1506000949350505050565b80516001600160a01b0316600090815260046020526040812054801580613dd65750600180820381548110613db657fe5b9060005260206000209060040201600201601c9054906101000a900460ff165b15613e1c5782516040516001600160a01b03909116907fe209c46bebf57cf265d5d9009a00870e256d9150f3ed5281ab9d9eb3cec6e4be90600090a2600091505061130b565b600154600554600019820111801590613e725784516040516001600160a01b03909116907fe209c46bebf57cf265d5d9009a00870e256d9150f3ed5281ab9d9eb3cec6e4be90600090a26000935050505061130b565b600580546001908101909155805481906000198601908110613e9057fe5b6000918252602082206002600490920201018054921515600160e01b0260ff60e01b199093169290921790915585516040516001600160a01b03909116917ff226e7d8f547ff903d9d419cf5f54e0d7d07efa9584135a53a057c5f1f27f49a91a2506000949350505050565b6000610ea283836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506156ee565b6000610ea283836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250615725565b600082613f8f575060006113bb565b82820282848281613f9c57fe5b0414610ea25760405162461bcd60e51b8152600401610c3b90616ac6565b600082820183811015610ea25760405162461bcd60e51b8152600401610c3b90616665565b60008060018381548110613fef57fe5b906000526020600020906004020160030154905060006001808054905003905060016140196125ac565b511161404e5760006001858154811061402e57fe5b9060005260206000209060040201600301819055506000925050506113bb565b846001600160a01b03167f3b6f9ef90462b512a1293ecec018670bf7b7f1876fb727590a8a6d7643130a70836040516140879190616ef1565b60405180910390a26001600160a01b038516600090815260046020526040812055835b6001546000190181101561427457600181600101815481106140c857fe5b9060005260206000209060040201600182815481106140e357fe5b60009182526020909120825460049092020180546001600160a01b03199081166001600160a01b0393841617825560018085015481840180548416918616919091179055600280860180549185018054909416919095161780835584546001600160401b03600160a01b91829004160267ffffffffffffffff60a01b1990911617808355935460ff600160e01b918290041615150260ff60e01b19909416939093179055600392830154920191909155600b8054909183019081106141a457fe5b9060005260206000209060160201600b82815481106141bf57fe5b600091825260209091208254601690920201908155600180830154818301805460ff909216151560ff1990921691909117905560028084018054614216938386019390821615610100026000190190911604615ebb565b5061422960038281019084016013615f30565b5090505080600101600460006001848154811061424257fe5b600091825260208083206004909202909101546001600160a01b031683528201929092526040019020556001016140aa565b50600180548061428057fe5b60008281526020812060046000199093019283020180546001600160a01b0319908116825560018201805490911690556002810180546001600160e81b0319169055600301559055600b8054806142d357fe5b60008281526020812060166000199093019283020181815560018101805460ff19169055906143056002830182615f5a565b614313600383016000615f9e565b50509055600081838161432257fe5b04905080156143865760015460005b8181101561438357826001828154811061434757fe5b906000526020600020906004020160030154016001828154811061436757fe5b6000918252602090912060036004909202010155600101614331565b50505b50600195945050505050565b6001548151604080518281526020808402820101909152606092919083908280156143d157816020015b60608152602001906001900390816143bc5790505b50600b5490915083146143e857925061130b915050565b60005b828110156144f757600b60016004600089858151811061440757fe5b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002054038154811061443b57fe5b600091825260209182902060026016909202018101805460408051601f6000196101006001861615020190931694909404918201859004850284018501905280835291929091908301828280156144d35780601f106144a8576101008083540402835291602001916144d3565b820191906000526020600020905b8154815290600101906020018083116144b657829003601f168201915b50505050508282815181106144e457fe5b60209081029190910101526001016143eb565b50949350505050565b60005b8281101561464d57600082878388016040516020016145239291906162ea565b6040516020818303038152906040528051906020012060001c8161454357fe5b06905080850182870114614644576000898388018151811061456157fe5b602002602001015190506060898489018151811061457b57fe5b602002602001015190508a8388018151811061459357fe5b60200260200101518b858a01815181106145a957fe5b60200260200101906001600160a01b031690816001600160a01b031681525050818b848901815181106145d857fe5b60200260200101906001600160a01b031690816001600160a01b031681525050898388018151811061460657fe5b60200260200101518a858a018151811061461c57fe5b6020026020010181905250808a8489018151811061463657fe5b602002602001018190525050505b50600101614503565b5050505050505050565b600980546001908101909155600b80548390811061467157fe5b906000526020600020906016020160010160006101000a81548160ff02191690831515021790555043600b82815481106146a757fe5b600091825260208220601690910201919091556040516001600160a01b038416917ff62981a567ec3cec866c6fa93c55bcdf841d6292d18b8d522ececa769375d82d91a25050565b60008160405160200161470291906162ce565b604051602081830303815290604052805190602001208360405160200161472991906162ce565b6040516020818303038152906040528051906020012014905092915050565b015190565b6001600160a01b038116600090815260046020526040812054806147765750600019905061130b565b60018103905060006001828154811061478b57fe5b90600052602060002090600402016003015490506000600183815481106147ae57fe5b6000918252602090912060036004909202010155600154604051600019909101906001600160a01b038616907f8cd4e147d8af98a9e3b6724021b8bf6aed2e5dac71c38f2dce8161b82585b25d90614807908590616ef1565b60405180910390a28061481f5782935050505061130b565b600081838161482a57fe5b04905080156148e65760005b8481101561488857816001828154811061484c57fe5b906000526020600020906004020160030154016001828154811061486c57fe5b6000918252602090912060036004909202010155600101614836565b50600180549085015b818110156148e35782600182815481106148a757fe5b90600052602060002090600402016003015401600182815481106148c757fe5b6000918252602090912060036004909202010155600101614891565b50505b5091949350505050565b6148f8615fad565b506040805180820190915281518152602082810190820152919050565b61491d615e66565b61492682615751565b61492f57600080fd5b600061493e836020015161578b565b60208085015160408051808201909152868152920190820152915050919050565b6000614969615fad565b505080518051602091820151919092015191011190565b614988615fad565b6149918261495f565b61499a57600080fd5b602082015160006149aa826157ee565b80830160209586015260408051808201909152908152938401919091525090919050565b8051600090158015906149e357508151602110155b6149ec57600080fd5b60006149fb836020015161578b565b90508083600001511015614a215760405162461bcd60e51b8152600401610c3b90616c84565b8251602080850151830180519284900392918310156144f757506020919091036101000a90049392505050565b6060614a5982615751565b614a6257600080fd5b6000614a6d836158cf565b9050606081604051908082528060200260200182016040528015614aab57816020015b614a98615fad565b815260200190600190039081614a905790505b5090506000614abd856020015161578b565b60208601510190506000805b84811015614b1457614ada836157ee565b9150604051806040016040528083815260200184815250848281518110614afd57fe5b602090810291909101015291810191600101614ac9565b509195945050505050565b614b27615e86565b60606000614b33615e86565b6060614b3d615e66565b614b4687614915565b90506000805b614b558361495f565b15614c2a5780614b8057614b70614b6b84614980565b61592b565b6001600160a01b03168552614c22565b8060011415614ba857614b95614b6b84614980565b6001600160a01b03166020860152614c22565b8060021415614bd057614bbd614b6b84614980565b6001600160a01b03166040860152614c22565b8060031415614bfc57614be5612f6484614980565b6001600160401b0316606086015260019150614c22565b8060041415614c1d57614c16614c1184614980565b615945565b9350614c22565b614c2a565b600101614b4c565b50929791965091945092505050565b60606113bb614c47836159b5565b615a9b565b6060815160001415614c6d575060408051600081526020810190915261130b565b606082600081518110614c7c57fe5b602002602001015190506000600190505b8351811015614cbd57614cb382858381518110614ca657fe5b6020026020010151615aed565b9150600101614c8d565b50610ea2614cd0825160c060ff16615b6a565b82615aed565b606080600080808080614ce76126a8565b6001549091505b8015614df557600181039250600b8381548110614d0757fe5b600091825260209091206001601690920201015460ff16614d2757614dec565b60018381548110614d3457fe5b60009182526020909120600490910201546001600160a01b03169450614d5b858484612d28565b9350831580614d6e575060018a51038610155b15614d7857614dec565b60005b8a51811015614dea57856001600160a01b03168b8281518110614d9a57fe5b6020026020010151600001516001600160a01b03161415614de25760018b8281518110614dc357fe5b6020908102919091010151901515608090910152600190960195614dea565b600101614d7b565b505b60001901614cee565b5084895103604051908082528060200260200182016040528015614e3357816020015b614e20615e86565b815260200190600190039081614e185790505b50965084895103604051908082528060200260200182016040528015614e6d57816020015b6060815260200190600190039081614e585790505b5095506000915060005b8951811015614f0157898181518110614e8c57fe5b602002602001015160800151614ef957898181518110614ea857fe5b6020026020010151888481518110614ebc57fe5b6020026020010181905250888181518110614ed357fe5b6020026020010151878481518110614ee757fe5b60200260200101819052508260010192505b600101614e77565b5050505050505b9250929050565b600154825160005b8281101561502c576001614f29615e86565b60018381548110614f3657fe5b600091825260208083206040805160c08101825260049490940290910180546001600160a01b0390811685526001820154811693850193909352600281015492831691840191909152600160a01b82046001600160401b03166060840152600160e01b90910460ff16151560808301526003015460a082015291505b8481101561500057878181518110614fc657fe5b6020026020010151600001516001600160a01b031682600001516001600160a01b03161415614ff85760009250615000565b600101614fb2565b5081156150225780516001600160a01b03166000908152600460205260408120555b5050600101614f17565b50808211156150eb57805b828110156150e957600180548061504a57fe5b60008281526020812060046000199093019283020180546001600160a01b0319908116825560018201805490911690556002810180546001600160e81b0319169055600301559055600b80548061509d57fe5b60008281526020812060166000199093019283020181815560018101805460ff19169055906150cf6002830182615f5a565b6150dd600383016000615f9e565b50509055600101615037565b505b60008183106150fa57816150fc565b825b905060005b818110156154a0576151ae86828151811061511857fe5b60200260200101516001838154811061512d57fe5b60009182526020918290206040805160c08101825260049390930290910180546001600160a01b0390811684526001820154811694840194909452600281015493841691830191909152600160a01b83046001600160401b03166060830152600160e01b90920460ff161515608082015260039091015460a0820152615c3c565b6153625780600101600460008884815181106151c657fe5b6020026020010151600001516001600160a01b03166001600160a01b031681526020019081526020016000208190555085818151811061520257fe5b60200260200101516001828154811061521757fe5b6000918252602091829020835160049092020180546001600160a01b039283166001600160a01b0319918216178255928401516001820180549184169185169190911790556040840151600282018054606087015160808801511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b1995909716929097169190911792909216939093171692909217905560a09091015160039091015584518590829081106152d257fe5b6020026020010151600b82815481106152e757fe5b9060005260206000209060160201600201908051906020019061530b929190615d9b565b506000600b828154811061531b57fe5b60009182526020822060169190910201600101805460ff191692151592909217909155600b80548390811061534c57fe5b6000918252602090912060169091020155615498565b61542885828151811061537157fe5b6020026020010151600b838154811061538657fe5b600091825260209182902060026016909202018101805460408051601f60001961010060018616150201909316949094049182018590048502840185019052808352919290919083018282801561541e5780601f106153f35761010080835404028352916020019161541e565b820191906000526020600020905b81548152906001019060200180831161540157829003601f168201915b5050505050615cbd565b6154735784818151811061543857fe5b6020026020010151600b828154811061544d57fe5b90600052602060002090601602016002019080519060200190615471929190615d9b565b505b60006001828154811061548257fe5b9060005260206000209060040201600301819055505b600101615101565b5082821115615678576154b1615d6c565b835b83811015615675578581815181106154c757fe5b6020026020010151826040018190525060018782815181106154e557fe5b6020908102919091018101518254600181810185556000948552838520835160049093020180546001600160a01b039384166001600160a01b0319918216178255848601518284018054918616918316919091179055604080860151600284018054606089015160808a01511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b1995909a1692909616919091179290921696909617169190911790935560a090930151600390930192909255600b805492830181559093528451601690910260008051602061714f83398151915281019182558583015160008051602061718f8339815191528201805491151560ff199092169190911790559285015180518694929361561b9360008051602061716f83398151915201920190615d9b565b5060608201516156319060038301906013615e15565b505050806001016004600089848151811061564857fe5b602090810291909101810151516001600160a01b03168252810191909152604001600020556001016154b3565b50505b6000600981905560015493505b838110156156e6576000600b828154811061569c57fe5b60009182526020822060169190910201600101805460ff191692151592909217909155600b8054839081106156cd57fe5b6000918252602090912060169091020155600101615685565b505050505050565b6000818361570f5760405162461bcd60e51b8152600401610c3b919061646f565b50600083858161571b57fe5b0495945050505050565b600081848411156157495760405162461bcd60e51b8152600401610c3b919061646f565b505050900390565b80516000906157625750600061130b565b6020820151805160001a9060c08210156157815760009250505061130b565b5060019392505050565b8051600090811a60808110156157a557600091505061130b565b60b88110806157c0575060c081108015906157c0575060f881105b156157cf57600191505061130b565b60c08110156157e35760b51901905061130b565b60f51901905061130b565b80516000908190811a608081101561580957600191506158c8565b60b881101561581e57607e19810191506158c8565b60c081101561586f57600060b78203600186019550806020036101000a8651049150600181018201935050808310156158695760405162461bcd60e51b8152600401610c3b90616a13565b506158c8565b60f88110156158845760be19810191506158c8565b600060f78203600186019550806020036101000a8651049150600181018201935050808310156158c65760405162461bcd60e51b8152600401610c3b90616a13565b505b5092915050565b80516000906158e05750600061130b565b600080905060006158f4846020015161578b565b602085015185519181019250015b8082101561592257615913826157ee565b82019150826001019250615902565b50909392505050565b805160009060151461593c57600080fd5b6113bb826149ce565b805160609061595357600080fd5b6000615962836020015161578b565b83516040805191839003808352601f19601f8201168301602001909152919250606090828015615999576020820181803683370190505b50905060008160200190506144f7848760200151018285615d21565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff1984166159f957506018615a1d565b6fffffffffffffffffffffffffffffffff198416615a1957506010615a1d565b5060005b6020811015615a5357818181518110615a3257fe5b01602001516001600160f81b03191615615a4b57615a53565b600101615a1d565b60008160200390506060816040519080825280601f01601f191660200182016040528015615a88576020820181803683370190505b5080830196909652508452509192915050565b606081516001148015615acd5750607f60f81b82600081518110615abb57fe5b01602001516001600160f81b03191611155b15615ad957508061130b565b6113bb615aeb8351608060ff16615b6a565b835b6060806040519050835180825260208201818101602087015b81831015615b1e578051835260209283019201615b06565b50855184518101855292509050808201602086015b81831015615b4b578051835260209283019201615b33565b508651929092011591909101601f01601f191660405250905092915050565b6060680100000000000000008310615b945760405162461bcd60e51b8152600401610c3b90616817565b60408051600180825281830190925260609160208201818036833701905050905060378411615bee5782840160f81b81600081518110615bd057fe5b60200101906001600160f81b031916908160001a90535090506113bb565b6060615bf9856159b5565b90508381510160370160f81b82600081518110615c1257fe5b60200101906001600160f81b031916908160001a905350615c338282615aed565b95945050505050565b805182516000916001600160a01b039182169116148015615c76575081602001516001600160a01b031683602001516001600160a01b0316145b8015615c9b575081604001516001600160a01b031683604001516001600160a01b0316145b8015610ea25750506060908101519101516001600160401b0390811691161490565b815181516000916001918114808314615cd95760009250615d17565b600160208701838101602088015b600284838510011415615d12578051835114615d065760009650600093505b60209283019201615ce7565b505050505b5090949350505050565b80615d2b57610c5b565b5b60208110615d4b578251825260209283019290910190601f1901615d2c565b915181516020939093036101000a6000190180199091169216919091179052565b60405180608001604052806000815260200160001515815260200160608152602001615d96615fc7565b905290565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10615ddc57805160ff1916838001178555615e09565b82800160010185558215615e09579182015b82811115615e09578251825591602001919060010190615dee565b506126e3929150615fe6565b8260138101928215615e095791602002820182811115615e09578251825591602001919060010190615dee565b6040518060600160405280600060ff16815260200160608152602001606081525090565b6040518060400160405280615e79615fad565b8152602001600081525090565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a081019190915290565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10615ef45780548555615e09565b82800160010185558215615e0957600052602060002091601f016020900482015b82811115615e09578254825591600101919060010190615f15565b8260138101928215615e095791820182811115615e09578254825591600101919060010190615f15565b50805460018160011615610100020316600290046000825580601f10615f805750611517565b601f0160209004906000526020600020908101906115179190615fe6565b50611517906013810190615fe6565b604051806040016040528060008152602001600081525090565b6040518061026001604052806013906020820280368337509192915050565b61269591905b808211156126e35760008155600101615fec565b60008083601f840112616011578182fd5b5081356001600160401b03811115616027578182fd5b6020830191508360208083028501011115614f0857600080fd5b60008083601f840112616052578182fd5b5081356001600160401b03811115616068578182fd5b602083019150836020828501011115614f0857600080fd5b600060208284031215616091578081fd5b81356001600160a01b0381168114610ea2578182fd5b600080600080604085870312156160bc578283fd5b84356001600160401b03808211156160d2578485fd5b6160de88838901616000565b909650945060208701359150808211156160f6578384fd5b5061610387828801616000565b95989497509550505050565b600060208284031215616120578081fd5b81518015158114610ea2578182fd5b60008060008060408587031215616144578384fd5b84356001600160401b038082111561615a578586fd5b61616688838901616041565b9096509450602087013591508082111561617e578384fd5b5061610387828801616041565b60006020828403121561619c578081fd5b5035919050565b6000602082840312156161b4578081fd5b5051919050565b600080604083850312156161cd578182fd5b505080516020909101519092909150565b6000806000604084860312156161f2578283fd5b833560ff81168114616202578384fd5b925060208401356001600160401b0381111561621c578283fd5b61622886828701616041565b9497909650939450505050565b6000815180845260208085019450808401835b8381101561626d5781516001600160a01b031687529582019590820190600101616248565b509495945050505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b600081518084526162ba816020860160208601616f57565b601f01601f19169290920160200192915050565b600082516162e0818460208701616f57565b9190910192915050565b918252602082015260400190565b6001600160a01b0391909116815260200190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b03968716815294861660208601529290941660408401526001600160401b03166060830152911515608082015260a081019190915260c00190565b600060208252610ea26020830184616235565b60006040825261638d6040830185616235565b602083820381850152818551808452828401915082838202850101838801865b838110156163db57601f198784030185526163c98383516162a2565b948601949250908501906001016163ad565b50909998505050505050505050565b6000608082526163fd6080830187616235565b828103602084810191909152865180835287820192820190845b8181101561643357845183529383019391830191600101616417565b505084810360408601526164478188616235565b93505050506001600160401b038316606083015295945050505050565b901515815260200190565b600060208252610ea260208301846162a2565b600060408252616496604083018688616278565b82810360208401526164a9818587616278565b979650505050505050565b6020808252601c908201527f6c656e677468206f66206275726e526174696f206d69736d6174636800000000604082015260600190565b60208082526026908201527f6c656e677468206f66206d61784e756d4f664d61696e7461696e696e67206d696040820152650e6dac2e8c6d60d31b606082015260800190565b6020808252601b908201527f6261746368207472616e736665722072657475726e2066616c73650000000000604082015260600190565b6020808252602c908201527f6c656e677468206f66206d61784e756d4f66576f726b696e6743616e6469646160408201526b0e8cae640dad2e6dac2e8c6d60a31b606082015260800190565b60208082526025908201527f6c656e677468206f66206d61696e7461696e536c6173685363616c65206d69736040820152640dac2e8c6d60db1b606082015260800190565b6020808252818101527f6c656e677468206f66206e756d4f66436162696e657473206d69736d61746368604082015260600190565b60208082526019908201527f74686520636f6e7472616374206e6f7420696e69742079657400000000000000604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b60208082526028908201527f746865206e756d4f66436162696e657473206d75737420626520677265617465604082015267072207468616e20360c41b606082015260800190565b60208082526039908201527f746865206e756d4f66436162696e657473206d757374206265206c657373207460408201527f68616e204d41585f4e554d5f4f465f56414c494441544f525300000000000000606082015260800190565b60208082526029908201527f746865206e756d626572206f662076616c696461746f727320657863656564206040820152681d1a19481b1a5b5a5d60ba1b606082015260800190565b60208082526022908201527f63616e206e6f7420646f207468697320747769636520696e206f6e6520626c6f604082015261636b60f01b606082015260800190565b6020808252602b908201527f746865206275726e526174696f206d757374206265206e6f206772656174657260408201526a0207468616e2031303030360ac1b606082015260800190565b6020808252600e908201526d696e70757420746f6f206c6f6e6760901b604082015260600190565b60208082526037908201527f746865206d61784e756d4f664d61696e7461696e696e67206d7573742062652060408201527f6c657373207468616e206e756d4f66436162696e657473000000000000000000606082015260800190565b6020808252602b908201527f6475706c696361746520636f6e73656e7375732061646472657373206f66207660408201526a185b1a59185d1bdc94d95d60aa1b606082015260800190565b60208082526027908201527f7468652065787069726554696d655365636f6e64476170206973206f7574206f604082015266662072616e676560c81b606082015260800190565b6020808252601590820152746465706f7369742076616c7565206973207a65726f60581b604082015260600190565b60208082526049908201527f746865206d61784e756d4f66576f726b696e6743616e64696461746573206d7560408201527f7374206265206e6f742067726561746572207468616e206d61784e756d4f6643606082015268616e6469646174657360b81b608082015260a00190565b60208082526027908201527f7468652066696e616c697479526577617264526174696f206973206f7574206f604082015266662072616e676560c81b606082015260800190565b6020808252601190820152706164646974696f6e206f766572666c6f7760781b604082015260600190565b60208082526023908201527f63616e206e6f7420656e7465722054656d706f72617279204d61696e74656e616040820152626e636560e81b606082015260800190565b60208082526025908201527f6c656e677468206f66206a61696c2076616c696461746f7273206d757374206260408201526465206f6e6560d81b606082015260800190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252602e908201527f746865206d6573736167652073656e646572206d75737420626520676f76657260408201526d1b985b98d94818dbdb9d1c9858dd60921b606082015260800190565b60208082526025908201527f6c656e677468206f66206d61784e756d4f6643616e64696461746573206d69736040820152640dac2e8c6d60db1b606082015260800190565b6020808252601290820152716e6f7420696e206d61696e74656e616e636560701b604082015260600190565b60208082526021908201527f666565206973206c6172676572207468616e2044555354595f494e434f4d494e6040820152604760f81b606082015260800190565b60208082526019908201527f74686520636f6e747261637420616c726561647920696e697400000000000000604082015260600190565b60208082526026908201527f6c656e677468206f662066696e616c697479526577617264526174696f206d696040820152650e6dac2e8c6d60d31b606082015260800190565b6020808252601a908201527f6c656e677468206973206c657373207468616e206f6666736574000000000000604082015260600190565b60208082526026908201527f6c656e677468206f662065787069726554696d655365636f6e64476170206d696040820152650e6dac2e8c6d60d31b606082015260800190565b60208082526017908201527f6f6e6c792063757272656e742076616c696461746f7273000000000000000000604082015260600190565b60208082526021908201527f6661696c656420746f20706172736520696e69742076616c696461746f7253656040820152601d60fa1b606082015260800190565b6020808252602f908201527f746865206d6573736167652073656e646572206d7573742062652063726f737360408201526e0818da185a5b8818dbdb9d1c9858dd608a1b606082015260800190565b6020808252602d908201527f746865206d6573736167652073656e646572206d75737420626520746865206260408201526c3637b1b590383937b23ab1b2b960991b606082015260800190565b6020808252603e908201527f746865206d61696e7461696e536c6173685363616c65206d757374206265206760408201527f726561746572207468616e203020616e64206c657373207468616e2031300000606082015260800190565b6020808252600d908201526c756e6b6e6f776e20706172616d60981b604082015260600190565b60208082526029908201527f746865206d6573736167652073656e646572206d75737420626520736c6173686040820152680818dbdb9d1c9858dd60ba1b606082015260800190565b61ffff91909116815260200190565b90815260200190565b6000848252831515602083015260606040830152615c3360608301846162a2565b63ffffffff91909116815260200190565b60ff91909116815260200190565b600060ff8516825260406020830152615c33604083018486616278565b60005b83811015616f72578181015183820152602001616f5a565b83811115612c48575050600091015256fef901a880f901a4f844941284214b9b9c85549ab3d2b972df0deef66ac2c9946ddf42a51534fc98d0c0a3b42c963cace8441ddf946ddf42a51534fc98d0c0a3b42c963cace8441ddf8410000000f84494a2959d3f95eae5dc7d70144ce1b73b403b7eb6e0948081ef03f1d9e0bb4a5bf38f16285c879299f07f948081ef03f1d9e0bb4a5bf38f16285c879299f07f8410000000f8449435552c16704d214347f29fa77f77da6d75d7c75294dc4973e838e3949c77aced16ac2315dc2d7ab11194dc4973e838e3949c77aced16ac2315dc2d7ab1118410000000f84494980a75ecd1309ea12fa2ed87a8744fbfc9b863d594cc6ac05c95a99c1f7b5f88de0e3486c82293b27094cc6ac05c95a99c1f7b5f88de0e3486c82293b2708410000000f84494f474cf03cceff28abc65c9cbae594f725c80e12d94e61a183325a18a173319dd8e19c8d069459e217594e61a183325a18a173319dd8e19c8d069459e21758410000000f84494b71b214cb885500844365e95cd9942c7276e7fd894d22ca3ba2141d23adab65ce4940eb7665ea2b6a794d22ca3ba2141d23adab65ce4940eb7665ea2b6a7841000000070e72399380dcfb0338abc03dc8d47f9f470ada8e769c9a78d644ea97385ecb20175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db90175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01dbb0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01dbaa2646970667358221220bc53b84b66ec5288714012f6e0e7cdc85eb3fd6718cf69ef36b3579924bc204664736f6c63430006040033", + }, + { + ContractAddr: common.HexToAddress(SlashContract), + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/b144718e94d7a1ebb24a7103202300f08826f369", + Code: "608060405234801561001057600080fd5b506004361061027f5760003560e01c80637942fd051161015c578063c80d4b8f116100ce578063dc927faf11610087578063dc927faf146104ad578063e1c7392a146104b5578063f9a2bbc7146104bd578063fc3e5908146104c5578063fc4333cd146104cd578063fd6a6879146104d55761027f565b8063c80d4b8f1461045c578063c81b166214610464578063c8509d811461046c578063c96be4cb1461047f578063cc844b7314610492578063d2a42e4b146104a55761027f565b80639dc09262116101205780639dc0926214610421578063a1a11bf514610429578063a78abc1614610431578063ab51bb9614610439578063ac0af62914610441578063ac431751146104495761027f565b80637942fd05146103ee5780638256ace6146103f6578063831d65d1146103fe57806396713da9146104115780639bc8e4f2146104195761027f565b8063493279b1116101f557806362b72cf5116101b957806362b72cf5146103be5780636e47b482146103c657806370fd5bad146103ce578063718a8aa8146103d657806375d47a0a146103de5780637912a65d146103e65761027f565b8063493279b11461037c5780634bf6c8821461039157806351e8067214610399578063567a372d146103a15780635bfb4990146103a95761027f565b806335aa2e441161024757806335aa2e441461030e57806337c8dab914610321578063389f4f71146103425780633a63f4b1146103575780633dffc3871461035f57806343756e5c146103745761027f565b80630bee7a67146102845780630e2374a5146102a25780631182b875146102b757806322d1e80b146102d757806323bac5a2146102ec575b600080fd5b61028c6104dd565b60405161029991906132a6565b60405180910390f35b6102aa6104e2565b6040516102999190612b84565b6102ca6102c5366004612aba565b6104e8565b6040516102999190612bbc565b6102df61054e565b6040516102999190612bb1565b6102ff6102fa366004612868565b610557565b6040516102999392919061328e565b6102aa61031c366004612a8a565b61057a565b61033461032f366004612868565b6105a1565b604051610299929190613280565b61034a6105f8565b6040516102999190613256565b61034a6105fe565b610367610604565b60405161029991906132b7565b6102aa610609565b61038461060f565b6040516102999190613247565b610367610615565b6102aa61061a565b61034a610620565b6103bc6103b7366004612868565b610626565b005b61034a6106d1565b6102aa6106d7565b6103676106dd565b6103676106e2565b6102aa6106e7565b61034a6106ed565b6103676106f2565b6103346106f7565b6103bc61040c366004612aba565b610701565b610367610813565b61034a610818565b6102aa610823565b6102aa610829565b6102df61082f565b61028c610838565b61034a61083d565b6103bc61045736600461296e565b610842565b61034a610ce1565b6102aa610ce6565b6103bc61047a366004612aba565b610cec565b6103bc61048d366004612868565b610d5d565b6103bc6104a03660046129d7565b61114e565b61034a61169b565b6102aa6116a0565b6103bc6116a6565b6102aa6116e2565b6103676116e8565b6103bc6116ed565b6102aa611b36565b606481565b61200181565b606033612000146105145760405162461bcd60e51b815260040161050b906130cd565b60405180910390fd5b60005460ff166105365760405162461bcd60e51b815260040161050b90612c9d565b60405162461bcd60e51b815260040161050b90613190565b60075460ff1681565b600260208190526000918252604090912080546001820154919092015460ff1683565b6001818154811061058757fe5b6000918252602090912001546001600160a01b0316905081565b6000806105ac61264f565b5050506001600160a01b0316600090815260026020818152604092839020835160608101855281548082526001830154938201849052919093015460ff16151592909301919091529091565b60055481565b60065481565b600181565b61100181565b6102ca81565b600881565b61200081565b60045481565b33611000146106475760405162461bcd60e51b815260040161050b90612ee1565b60005460ff166106695760405162461bcd60e51b815260040161050b90612c9d565b61200063f7a251d7600b61067c84611b3c565b60006040518463ffffffff1660e01b815260040161069c939291906132c5565b600060405180830381600087803b1580156106b657600080fd5b505af11580156106ca573d6000803e3d6000fd5b5050505050565b60035481565b61100581565b600281565b601081565b61100881565b603281565b600b81565b6004546005549091565b33612000146107225760405162461bcd60e51b815260040161050b906130cd565b60005460ff166107445760405162461bcd60e51b815260040161050b90612c9d565b61074c612672565b600061078d84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611c0f92505050565b9150915080156107d45781516040517f7f0956d47419b9525356e7111652b653b530ec6f5096dccc04589bc38e629967916107c7916132a6565b60405180910390a16106ca565b81516040517f7d45f62d17443dd4547bca8a8112c60e2385669318dc300ec61a5d2492f262e791610804916132a6565b60405180910390a15050505050565b600981565b662386f26fc1000081565b61100781565b61100681565b60005460ff1681565b600081565b600481565b60005460ff166108645760405162461bcd60e51b815260040161050b90612c9d565b33611007146108855760405162461bcd60e51b815260040161050b90612f8a565b6108f084848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260148152731b5a5cd9195b59585b9bdc951a1c995cda1bdb1960621b60208201529150611c8f9050565b1561098b57602081146109155760405162461bcd60e51b815260040161050b90612e6d565b604080516020601f840181900481028201810190925282815260009161095391858580838501838280828437600092019190915250611ce992505050565b905060018110158015610967575060055481105b6109835760405162461bcd60e51b815260040161050b90613088565b600455610c9e565b6109f184848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600f81526e19995b1bdb9e551a1c995cda1bdb19608a1b60208201529150611c8f9050565b15610a8d5760208114610a165760405162461bcd60e51b815260040161050b90612fd8565b604080516020601f8401819004810282018101909252828152600091610a5491858580838501838280828437600092019190915250611ce992505050565b90506103e88111158015610a69575060045481115b610a855760405162461bcd60e51b815260040161050b90612d0b565b600555610c9e565b610b0184848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601881527f66696e616c697479536c617368526577617264526174696f000000000000000060208201529150611c8f9050565b15610b9b5760208114610b265760405162461bcd60e51b815260040161050b906131c7565b604080516020601f8401819004810282018101909252828152600091610b6491858580838501838280828437600092019190915250611ce992505050565b9050600a8110158015610b775750606481105b610b935760405162461bcd60e51b815260040161050b90612e21565b600655610c9e565b610c0f84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601881527f656e61626c654d616c6963696f7573566f7465536c617368000000000000000060208201529150611c8f9050565b15610c865760208114610c345760405162461bcd60e51b815260040161050b90612d40565b604080516020601f8401819004810282018101909252828152610c709190848480838501838280828437600092019190915250611cee92505050565b6007805460ff1916911515919091179055610c9e565b60405162461bcd60e51b815260040161050b90613169565b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a84848484604051610cd39493929190612bcf565b60405180910390a150505050565b609681565b61100281565b3361200014610d0d5760405162461bcd60e51b815260040161050b906130cd565b60005460ff16610d2f5760405162461bcd60e51b815260040161050b90612c9d565b6040517f07db600eebe2ac176be8dcebad61858c245a4961bb32ca2aa3d159b09aa0810e90600090a1505050565b334114610d7c5760405162461bcd60e51b815260040161050b9061311c565b60005460ff16610d9e5760405162461bcd60e51b815260040161050b90612c9d565b6003544311610dbf5760405162461bcd60e51b815260040161050b90613212565b3a15610ddd5760405162461bcd60e51b815260040161050b90612f5c565b60405163155853f360e21b8152611000906355614fcc90610e02908490600401612b84565b60206040518083038186803b158015610e1a57600080fd5b505afa158015610e2e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e52919061294e565b610e5b57611147565b610e6361264f565b506001600160a01b0381166000908152600260208181526040928390208351606081018552815481526001820154928101929092529091015460ff161580159282019290925290610ebe576020810180516001019052610f17565b60016040820181905260208201819052805480820182556000919091527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf60180546001600160a01b0319166001600160a01b0384161790555b438152600554602082015181610f2957fe5b0661107557600060208201526040516335409f7f60e01b8152611000906335409f7f90610f5a908590600401612b84565b600060405180830381600087803b158015610f7457600080fd5b505af1158015610f88573d6000803e3d6000fd5b505050506120006001600160a01b031663f7a251d7600b610fa885611b3c565b60006040518463ffffffff1660e01b8152600401610fc8939291906132c5565b600060405180830381600087803b158015610fe257600080fd5b505af1925050508015610ff3575060015b611070573d808015611021576040519150601f19603f3d011682016040523d82523d6000602084013e611026565b606091505b50826001600160a01b03167fd7bc86ff5d08c8ab043edec743302aba2520e6635172a428bc956721db9e2d1c83602001518360405161106692919061325f565b60405180910390a2505b6110e1565b60045481602001518161108457fe5b066110e1576040516375abf10160e11b81526110009063eb57e202906110ae908590600401612b84565b600060405180830381600087803b1580156110c857600080fd5b505af11580156110dc573d6000803e3d6000fd5b505050505b6001600160a01b0382166000818152600260208181526040808420865181559186015160018301558581015191909201805460ff1916911515919091179055517fddb6012116e51abf5436d956a4f0ebd927e92c576ff96d7918290c8782291e3e9190a2505b5043600355565b60005460ff166111705760405162461bcd60e51b815260040161050b90612c9d565b604051630a83aaa960e31b81526110069063541d554890611195903390600401612b84565b60206040518083038186803b1580156111ad57600080fd5b505afa1580156111c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111e5919061294e565b6112015760405162461bcd60e51b815260040161050b90612c01565b60075460ff166112235760405162461bcd60e51b815260040161050b90612c68565b6006546112305760146006555b8051514361010090910111801561125257504381602001516000015161010001115b61126e5760405162461bcd60e51b815260040161050b90612c38565b80602001516020015181600001516020015114801561129c5750806020015160600151816000015160600151145b156112b95760405162461bcd60e51b815260040161050b90612eb4565b8051604081015190511080156112d85750602081015160408101519051105b6112f45760405162461bcd60e51b815260040161050b90612dea565b6020810151518151511080156113195750806000015160400151816020015160400151105b8061134457508051516020820151511080156113445750806020015160400151816000015160400151105b8061135e5750806020015160400151816000015160400151145b61137a5760405162461bcd60e51b815260040161050b90612cd4565b61138c81600001518260400151611d16565b80156113a557506113a581602001518260400151611d16565b6113c15760405162461bcd60e51b815260040161050b90612d8b565b6060806110006001600160a01b0316633b071dcc6040518163ffffffff1660e01b815260040160006040518083038186803b1580156113ff57600080fd5b505afa158015611413573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261143b919081019061288b565b9150915060005b81518110156115785761146c82828151811061145a57fe5b60200260200101518560400151611eee565b15611570576006546040516309a99b4f60e41b815260646110028031909302049190639a99b4f0906114a49033908590600401612b98565b602060405180830381600087803b1580156114be57600080fd5b505af11580156114d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114f69190612aa2565b506110006001600160a01b03166335409f7f85848151811061151457fe5b60200260200101516040518263ffffffff1660e01b81526004016115389190612b84565b600060405180830381600087803b15801561155257600080fd5b505af1158015611566573d6000803e3d6000fd5b5050505050611578565b600101611442565b50600061158a84604001516000611f52565b90506120006001600160a01b031663f7a251d7600b6115ac8760400151611f6e565b60006040518463ffffffff1660e01b81526004016115cc939291906132c5565b600060405180830381600087803b1580156115e657600080fd5b505af19250505080156115f7575060015b611669573d808015611625576040519150601f19603f3d011682016040523d82523d6000602084013e61162a565b606091505b50817fd58d1183100bd0932c0588f31c4205d6bc6168909765a96c41adbed3115f36288260405161165b9190612bbc565b60405180910390a250611695565b60405181907f7b78aadacff901d8b63d0dba4f86283d4db8aef27f9ed70413dd860f1c9532b690600090a25b50505050565b601481565b61100381565b60005460ff16156116c95760405162461bcd60e51b815260040161050b9061301a565b603260045560966005556000805460ff19166001179055565b61100081565b600381565b336110001461170e5760405162461bcd60e51b815260040161050b90612ee1565b60005460ff166117305760405162461bcd60e51b815260040161050b90612c9d565b60015461173c57611b34565b600154600090600019015b808211611b08576000805b8284101561186b5761176261264f565b600260006001878154811061177357fe5b60009182526020808320909101546001600160a01b0316835282810193909352604091820190208151606081018352815481526001820154938101939093526002015460ff161515908201526005549091506004900481602001511115611855576004600554816117e057fe5b0481602001510381602001818152505080600260006001888154811061180257fe5b6000918252602080832091909101546001600160a01b0316835282810193909352604091820190208351815591830151600183015591909101516002909101805460ff191691151591909117905561185f565b600192505061186b565b50836001019350611752565b828411611a025761187a61264f565b600260006001868154811061188b57fe5b60009182526020808320909101546001600160a01b0316835282810193909352604091820190208151606081018352815481526001820154938101939093526002015460ff161515908201526005549091506004900481602001511115611973576004600554816118f857fe5b0481602001510381602001818152505080600260006001878154811061191a57fe5b6000918252602080832091909101546001600160a01b03168352828101939093526040918201902083518155918301516001808401919091559201516002909101805460ff19169115159190911790559150611a029050565b600260006001868154811061198457fe5b60009182526020808320909101546001600160a01b031683528201929092526040018120818155600181810192909255600201805460ff191690558054806119c857fe5b600082815260209020810160001990810180546001600160a01b0319169055019055836119f55750611a02565b506000199092019161186b565b818015611a0c5750805b15611aeb576002600060018681548110611a2257fe5b60009182526020808320909101546001600160a01b031683528201929092526040018120818155600181810192909255600201805460ff19169055805484908110611a6957fe5b600091825260209091200154600180546001600160a01b039092169186908110611a8f57fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506001805480611ac857fe5b600082815260209020810160001990810180546001600160a01b03191690550190555b82611af7575050611b08565b505060019091019060001901611747565b6040517fcfdb3b6ccaeccbdc68be3c59c840e3b3c90f0a7c491f5fff1cf56cfda200dd9c90600090a150505b565b61100481565b60408051600480825260a08201909252606091829190816020015b6060815260200190600190039081611b57579050509050611b80836001600160a01b0316611fa9565b81600081518110611b8d57fe5b6020026020010181905250611ba143611fcc565b81600181518110611bae57fe5b6020908102919091010152611bc46102ca611fcc565b81600281518110611bd157fe5b6020026020010181905250611be542611fcc565b81600381518110611bf257fe5b6020026020010181905250611c0681611fdf565b9150505b919050565b611c17612672565b6000611c21612672565b611c29612684565b611c3a611c3586612069565b61208e565b90506000805b611c49836120d8565b15611c825780611c7557611c64611c5f846120f9565b612147565b63ffffffff16845260019150611c7a565b611c82565b600101611c40565b5091935090915050915091565b600081604051602001611ca29190612b68565b6040516020818303038152906040528051906020012083604051602001611cc99190612b68565b604051602081830303815290604052805190602001201490505b92915050565b015190565b8082015160009060ff811615611d08576001915081611d0e565b60009150815b505092915050565b60408051600480825260a0820190925260009160609190816020015b6060815260200190600190039081611d32575050604080516020808252818301909252919250606091908082018180368337019050509050611d778560000151611fcc565b82600081518110611d8457fe5b6020026020010181905250611d9f60208660200151836121c9565b611da8816121d9565b82600181518110611db557fe5b6020026020010181905250611dcd8560400151611fcc565b82600281518110611dda57fe5b6020026020010181905250611df560208660600151836121c9565b611dfe816121d9565b82600381518110611e0b57fe5b6020026020010181905250611e316020611e2484611fdf565b80519060200120836121c9565b6040805160b080825260e08201909252606091602082018180368337019050509050611e6181836000602061222f565b611e738187608001516020606061222f565b611e8181866080603061222f565b604080516001808252818301909252606091602082018180368337019050509050815160016020830182602086016066600019fa611ebe57600080fd5b506001611ecc826000612282565b60ff1614611ee1576000945050505050611ce3565b5060019695505050505050565b815181516000916001918114808314611f0a5760009250611f48565b600160208701838101602088015b600284838510011415611f43578051835114611f375760009650600093505b60209283019201611f18565b505050505b5090949350505050565b60008160200183511015611f6557600080fd5b50016020015190565b60408051600480825260a08201909252606091829190816020015b6060815260200190600190039081611f89579050509050611b80836121d9565b60408051600560a21b8318601482015260348101909152606090611c06816121d9565b6060611ce3611fda8361229e565b6121d9565b60608151600014156120005750604080516000815260208101909152611c0a565b60608260008151811061200f57fe5b602002602001015190506000600190505b8351811015612050576120468285838151811061203957fe5b6020026020010151612384565b9150600101612020565b50611c06612063825160c060ff16612401565b82612384565b6120716126a4565b506040805180820190915281518152602082810190820152919050565b612096612684565b61209f826124d3565b6120a857600080fd5b60006120b7836020015161250d565b60208085015160408051808201909152868152920190820152915050919050565b60006120e26126a4565b505080518051602091820151919092015191011190565b6121016126a4565b61210a826120d8565b61211357600080fd5b6020820151600061212382612570565b80830160209586015260408051808201909152908152938401919091525090919050565b80516000901580159061215c57508151602110155b61216557600080fd5b6000612174836020015161250d565b9050808360000151101561219a5760405162461bcd60e51b815260040161050b90613051565b8251602080850151830180519284900392918310156121c057826020036101000a820491505b50949350505050565b9091018181526020918201910152565b60608151600114801561220b5750607f60f81b826000815181106121f957fe5b01602001516001600160f81b03191611155b15612217575080611c0a565b611ce36122298351608060ff16612401565b83612384565b60005b818110156106ca5783818151811061224657fe5b602001015160f81c60f81b85848060010195508151811061226357fe5b60200101906001600160f81b031916908160001a905350600101612232565b6000816001018351101561229557600080fd5b50016001015190565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff1984166122e257506018612306565b6fffffffffffffffffffffffffffffffff19841661230257506010612306565b5060005b602081101561233c5781818151811061231b57fe5b01602001516001600160f81b031916156123345761233c565b600101612306565b60008160200390506060816040519080825280601f01601f191660200182016040528015612371576020820181803683370190505b5080830196909652508452509192915050565b6060806040519050835180825260208201818101602087015b818310156123b557805183526020928301920161239d565b50855184518101855292509050808201602086015b818310156123e25780518352602092830192016123ca565b508651929092011591909101601f01601f191660405250905092915050565b606068010000000000000000831061242b5760405162461bcd60e51b815260040161050b90612dc2565b604080516001808252818301909252606091602082018180368337019050509050603784116124855782840160f81b8160008151811061246757fe5b60200101906001600160f81b031916908160001a9053509050611ce3565b60606124908561229e565b90508381510160370160f81b826000815181106124a957fe5b60200101906001600160f81b031916908160001a9053506124ca8282612384565b95945050505050565b80516000906124e457506000611c0a565b6020820151805160001a9060c082101561250357600092505050611c0a565b5060019392505050565b8051600090811a6080811015612527576000915050611c0a565b60b8811080612542575060c08110801590612542575060f881105b15612551576001915050611c0a565b60c08110156125655760b519019050611c0a565b60f519019050611c0a565b80516000908190811a608081101561258b5760019150612648565b60b88110156125a057607e1981019150612648565b60c08110156125f157600060b78203600186019550806020036101000a8651049150600181018201935050808310156125eb5760405162461bcd60e51b815260040161050b90612f31565b50612648565b60f88110156126065760be1981019150612648565b600060f78203600186019550806020036101000a865104915060018101820193505080831015611d0e5760405162461bcd60e51b815260040161050b90612f31565b5092915050565b604051806060016040528060008152602001600081526020016000151581525090565b60408051602081019091526000815290565b60405180604001604052806126976126a4565b8152602001600081525090565b604051806040016040528060008152602001600081525090565b600082601f8301126126ce578081fd5b81516126e16126dc82613318565b6132f1565b818152915060208083019084810160005b84811015612757578151870188603f82011261270d57600080fd5b8381015161271d6126dc82613338565b81815260408b8184860101111561273357600080fd5b6127428388840183870161335c565b508652505092820192908201906001016126f2565b505050505092915050565b60008083601f840112612773578182fd5b50813567ffffffffffffffff81111561278a578182fd5b6020830191508360208285010111156127a257600080fd5b9250929050565b600082601f8301126127b9578081fd5b81356127c76126dc82613338565b91508082528360208285010111156127de57600080fd5b8060208401602084013760009082016020015292915050565b600060a08284031215612808578081fd5b61281260a06132f1565b905081358152602082013560208201526040820135604082015260608201356060820152608082013567ffffffffffffffff81111561285057600080fd5b61285c848285016127a9565b60808301525092915050565b600060208284031215612879578081fd5b813561288481613388565b9392505050565b6000806040838503121561289d578081fd5b825167ffffffffffffffff808211156128b4578283fd5b81850186601f8201126128c5578384fd5b805192506128d56126dc84613318565b80848252602080830192508084018a8283890287010111156128f5578788fd5b8794505b8685101561292057805161290c81613388565b8452600194909401939281019281016128f9565b508801519096509350505080821115612937578283fd5b50612944858286016126be565b9150509250929050565b60006020828403121561295f578081fd5b81518015158114612884578182fd5b60008060008060408587031215612983578182fd5b843567ffffffffffffffff8082111561299a578384fd5b6129a688838901612762565b909650945060208701359150808211156129be578384fd5b506129cb87828801612762565b95989497509550505050565b6000602082840312156129e8578081fd5b813567ffffffffffffffff808211156129ff578283fd5b81840160608187031215612a11578384fd5b612a1b60606132f1565b9250803582811115612a2b578485fd5b612a37878284016127f7565b845250602081013582811115612a4b578485fd5b612a57878284016127f7565b602085015250604081013582811115612a6e578485fd5b612a7a878284016127a9565b6040850152509195945050505050565b600060208284031215612a9b578081fd5b5035919050565b600060208284031215612ab3578081fd5b5051919050565b600080600060408486031215612ace578283fd5b833560ff81168114612ade578384fd5b9250602084013567ffffffffffffffff811115612af9578283fd5b612b0586828701612762565b9497909650939450505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b60008151808452612b5481602086016020860161335c565b601f01601f19169290920160200192915050565b60008251612b7a81846020870161335c565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b03929092168252602082015260400190565b901515815260200190565b6000602082526128846020830184612b3c565b600060408252612be3604083018688612b12565b8281036020840152612bf6818587612b12565b979650505050505050565b6020808252601f908201527f746865206d73672073656e646572206973206e6f7420612072656c6179657200604082015260600190565b6020808252601690820152751d1bdbc81bdb1908189b1bd8dac81a5b9d9bdb1d995960521b604082015260600190565b6020808252818101527f6d616c6963696f757320766f746520736c617368206e6f7420656e61626c6564604082015260600190565b60208082526019908201527f74686520636f6e7472616374206e6f7420696e69742079657400000000000000604082015260600190565b6020808252601a908201527f6e6f2076696f6c6174696f6e206f6620766f74652072756c6573000000000000604082015260600190565b6020808252818101527f7468652066656c6f6e795468726573686f6c64206f7574206f662072616e6765604082015260600190565b6020808252602b908201527f6c656e677468206f6620656e61626c654d616c6963696f7573566f7465536c6160408201526a0e6d040dad2e6dac2e8c6d60ab1b606082015260800190565b60208082526017908201527f766572696679207369676e6174757265206661696c6564000000000000000000604082015260600190565b6020808252600e908201526d696e70757420746f6f206c6f6e6760901b604082015260600190565b60208082526019908201527f7372634e756d20626967676572207468616e207461724e756d00000000000000604082015260600190565b6020808252602c908201527f7468652066696e616c69747920736c6173682072657761726420726174696f2060408201526b6f7574206f662072616e676560a01b606082015260800190565b60208082526027908201527f6c656e677468206f66206d697364656d65616e6f725468726573686f6c64206d6040820152660d2e6dac2e8c6d60cb1b606082015260800190565b60208082526013908201527274776f206964656e746963616c20766f74657360681b604082015260600190565b60208082526030908201527f746865206d6573736167652073656e646572206d7573742062652076616c696460408201526f185d1bdc94d95d0818dbdb9d1c9858dd60821b606082015260800190565b6020808252601190820152706164646974696f6e206f766572666c6f7760781b604082015260600190565b6020808252601490820152736761737072696365206973206e6f74207a65726f60601b604082015260600190565b6020808252602e908201527f746865206d6573736167652073656e646572206d75737420626520676f76657260408201526d1b985b98d94818dbdb9d1c9858dd60921b606082015260800190565b60208082526022908201527f6c656e677468206f662066656c6f6e795468726573686f6c64206d69736d61746040820152610c6d60f31b606082015260800190565b60208082526019908201527f74686520636f6e747261637420616c726561647920696e697400000000000000604082015260600190565b6020808252601a908201527f6c656e677468206973206c657373207468616e206f6666736574000000000000604082015260600190565b60208082526025908201527f746865206d697364656d65616e6f725468726573686f6c64206f7574206f662060408201526472616e676560d81b606082015260800190565b6020808252602f908201527f746865206d6573736167652073656e646572206d7573742062652063726f737360408201526e0818da185a5b8818dbdb9d1c9858dd608a1b606082015260800190565b6020808252602d908201527f746865206d6573736167652073656e646572206d75737420626520746865206260408201526c3637b1b590383937b23ab1b2b960991b606082015260800190565b6020808252600d908201526c756e6b6e6f776e20706172616d60981b604082015260600190565b6020808252601e908201527f7265636569766520756e65787065637465642073796e207061636b6167650000604082015260600190565b6020808252602b908201527f6c656e677468206f662066696e616c697479536c61736852657761726452617460408201526a0d2de40dad2e6dac2e8c6d60ab1b606082015260800190565b6020808252818101527f63616e206e6f7420736c61736820747769636520696e206f6e6520626c6f636b604082015260600190565b61ffff91909116815260200190565b90815260200190565b6000838252604060208301526132786040830184612b3c565b949350505050565b918252602082015260400190565b92835260208301919091521515604082015260600190565b63ffffffff91909116815260200190565b60ff91909116815260200190565b600060ff85168252606060208301526132e16060830185612b3c565b9050826040830152949350505050565b60405181810167ffffffffffffffff8111828210171561331057600080fd5b604052919050565b600067ffffffffffffffff82111561332e578081fd5b5060209081020190565b600067ffffffffffffffff82111561334e578081fd5b50601f01601f191660200190565b60005b8381101561337757818101518382015260200161335f565b838111156116955750506000910152565b6001600160a01b038116811461339d57600080fd5b5056fea2646970667358221220425f90ada15339392881582f35a21b784186e12ed634c463af0e608e49de659064736f6c63430006040033", + }, + { + ContractAddr: common.HexToAddress(SystemRewardContract), + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/b144718e94d7a1ebb24a7103202300f08826f369", + Code: "6080604052600436106101a05760003560e01c80637942fd05116100ec578063ac4317511161008a578063f9a2bbc711610064578063f9a2bbc714610550578063fb5478b314610565578063fc3e59081461057a578063fd6a68791461058f576101e4565b8063ac43175114610457578063c81b166214610526578063dc927faf1461053b576101e4565b80639dc09262116100c65780639dc0926214610403578063a1a11bf514610418578063a78abc161461042d578063ab51bb9614610442576101e4565b80637942fd05146103a057806396713da9146103b55780639a99b4f0146103ca576101e4565b80634bf6c882116101595780636e47b482116101335780636e47b4821461034c57806370fd5bad14610361578063718a8aa81461037657806375d47a0a1461038b576101e4565b80634bf6c882146102db57806351e80672146102f05780636d70f7ae14610305576101e4565b80630bee7a67146101e95780630e2374a5146102175780633a0b0eff146102485780633dffc3871461026f57806343756e5c1461029a578063493279b1146102af576101e4565b366101e45734156101e25760408051348152905133917f6c98249d85d88c3753a04a22230f595e4dc8d3dc86c34af35deeeedc861b89db919081900360200190a25b005b600080fd5b3480156101f557600080fd5b506101fe6105a4565b6040805163ffffffff9092168252519081900360200190f35b34801561022357600080fd5b5061022c6105a9565b604080516001600160a01b039092168252519081900360200190f35b34801561025457600080fd5b5061025d6105af565b60408051918252519081900360200190f35b34801561027b57600080fd5b506102846105b5565b6040805160ff9092168252519081900360200190f35b3480156102a657600080fd5b5061022c6105ba565b3480156102bb57600080fd5b506102c46105c0565b6040805161ffff9092168252519081900360200190f35b3480156102e757600080fd5b506102846105c6565b3480156102fc57600080fd5b5061022c6105cb565b34801561031157600080fd5b506103386004803603602081101561032857600080fd5b50356001600160a01b03166105d1565b604080519115158252519081900360200190f35b34801561035857600080fd5b5061022c6105ef565b34801561036d57600080fd5b506102846105f5565b34801561038257600080fd5b506102846105fa565b34801561039757600080fd5b5061022c6105ff565b3480156103ac57600080fd5b50610284610605565b3480156103c157600080fd5b5061028461060a565b3480156103d657600080fd5b5061025d600480360360408110156103ed57600080fd5b506001600160a01b03813516906020013561060f565b34801561040f57600080fd5b5061022c6107ba565b34801561042457600080fd5b5061022c6107c0565b34801561043957600080fd5b506103386107c6565b34801561044e57600080fd5b506101fe6107cf565b34801561046357600080fd5b506101e26004803603604081101561047a57600080fd5b81019060208101813564010000000081111561049557600080fd5b8201836020820111156104a757600080fd5b803590602001918460018302840111640100000000831117156104c957600080fd5b9193909290916020810190356401000000008111156104e757600080fd5b8201836020820111156104f957600080fd5b8035906020019184600183028401116401000000008311171561051b57600080fd5b5090925090506107d4565b34801561053257600080fd5b5061022c610b57565b34801561054757600080fd5b5061022c610b5d565b34801561055c57600080fd5b5061022c610b63565b34801561057157600080fd5b5061025d610b69565b34801561058657600080fd5b50610284610b75565b34801561059b57600080fd5b5061022c610b7a565b606481565b61200181565b60015481565b600181565b61100181565b6102ca81565b600881565b61200081565b6001600160a01b031660009081526002602052604090205460ff1690565b61100581565b600281565b601081565b61100881565b600b81565b600981565b6000805460ff1661068c57600260208190527fe57bda0a954a7c7381b17b2c763e646ba2c60f67292d287ba583603e2c1c41668054600160ff19918216811790925561100560009081527fe25235fc0de9d7165652bef0846fefda506174abb9a190f03d0f7bcc6146dbce80548316841790559282558254161790555b3360009081526002602052604090205460ff166106da5760405162461bcd60e51b815260040180806020018281038252602b815260200180610c68602b913960400191505060405180910390fd5b60004783106106e957476106eb565b825b9050670de0b6b3a76400008111156107085750670de0b6b3a76400005b8015610789576040516001600160a01b0385169082156108fc029083906000818181858888f19350505050158015610744573d6000803e3d6000fd5b506040805182815290516001600160a01b038616917ff8b71c64315fc33b2ead2adfa487955065152a8ac33d9d5193aafd7f45dc15a0919081900360200190a26107b3565b6040517fe589651933c2457488cc0d8e0941518abf748e799435e4e396d9c4d0b2db2d4d90600090a15b9392505050565b61100781565b61100681565b60005460ff1681565b600081565b33611007146108145760405162461bcd60e51b815260040180806020018281038252602e815260200180610cc2602e913960400191505060405180910390fd5b61087684848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600b81526a30b23227b832b930ba37b960a91b60208201529150610b809050565b1561094e57606082828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050825192935050601490911490506108f95760405162461bcd60e51b815260040180806020018281038252602c815260200180610cf0602c913960400191505060405180910390fd5b60148101516001600160a01b038116600081815260026020526040808220805460ff19166001179055517f9870d7fe5d112134c55844951dedf365363006d9c588db07c4c85af6322a06199190a25050610ac5565b6109b384848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600e81526d3232b632ba32a7b832b930ba37b960911b60208201529150610b809050565b15610a8857606082828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505082519293505060149091149050610a365760405162461bcd60e51b815260040180806020018281038252602f815260200180610c93602f913960400191505060405180910390fd5b60148101516001600160a01b038116600081815260026020526040808220805460ff19169055517fb40992a19dba61ea600e87fce607102bf5908dc89076217b6ca6ae195224f7029190a25050610ac5565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b61100281565b61100381565b61100081565b670de0b6b3a764000081565b600381565b61100481565b6000816040516020018082805190602001908083835b60208310610bb55780518252601f199092019160209182019101610b96565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b60208310610c235780518252601f199092019160209182019101610c04565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051602081830303815290604052805190602001201490509291505056fe6f6e6c79206f70657261746f7220697320616c6c6f77656420746f2063616c6c20746865206d6574686f646c656e677468206f662076616c756520666f722064656c6574654f70657261746f722073686f756c64206265203230746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e74726163746c656e677468206f662076616c756520666f72206164644f70657261746f722073686f756c64206265203230a2646970667358221220dfab8b447e80ff45b4921032d6fc749c076c81bafdd35dc3adbf21cb41cdac7964736f6c63430006040033", + }, + { + ContractAddr: common.HexToAddress(RelayerHubContract), + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/b144718e94d7a1ebb24a7103202300f08826f369", + Code: "608060405234801561001057600080fd5b50600436106102275760003560e01c80638f83ab1311610130578063c81b1662116100b8578063f3ae24151161007c578063f3ae2415146104e8578063f9a2bbc71461050e578063fc3e590814610516578063fd30d9b81461051e578063fd6a68791461052657610227565b8063c81b1662146104c0578063dc927faf146104c8578063dd91d1c5146104d0578063e1c7392a146104d8578063e79a198f146104e057610227565b8063a1a11bf5116100ff578063a1a11bf5146103de578063a74b83ca146103e6578063a78abc16146103ee578063ab51bb96146103f6578063ac431751146103fe57610227565b80638f83ab13146103a057806395468d26146103c657806396713da9146103ce5780639dc09262146103d657610227565b8063541d5548116101b3578063718a8aa811610182578063718a8aa81461034857806375d47a0a1461035057806378beee67146103585780637942fd051461037e5780637ae230881461038657610227565b8063541d5548146102d85780636a6a419e146103125780636e47b4821461033857806370fd5bad1461034057610227565b80633dffc387116101fa5780633dffc3871461028357806343756e5c146102a1578063493279b1146102a95780634bf6c882146102c857806351e80672146102d057610227565b806303aff02b1461022c578063049a5716146102365780630bee7a671461025a5780630e2374a51461027b575b600080fd5b61023461052e565b005b61023e610539565b604080516001600160a01b039092168252519081900360200190f35b610262610551565b6040805163ffffffff9092168252519081900360200190f35b61023e610556565b61028b61055c565b6040805160ff9092168252519081900360200190f35b61023e610561565b6102b1610567565b6040805161ffff9092168252519081900360200190f35b61028b61056d565b61023e610572565b6102fe600480360360208110156102ee57600080fd5b50356001600160a01b0316610578565b604080519115158252519081900360200190f35b6102fe6004803603602081101561032857600080fd5b50356001600160a01b0316610596565b61023e6105b4565b61028b6105ba565b61028b6105bf565b61023e6105c4565b6102346004803603602081101561036e57600080fd5b50356001600160a01b03166105ca565b61028b6107b2565b61038e6107b7565b60408051918252519081900360200190f35b610234600480360360208110156103b657600080fd5b50356001600160a01b03166107c4565b61038e610a03565b61028b610a0f565b61023e610a14565b61023e610a1a565b61023e610a20565b6102fe610a38565b610262610a41565b6102346004803603604081101561041457600080fd5b81019060208101813564010000000081111561042f57600080fd5b82018360208201111561044157600080fd5b8035906020019184600183028401116401000000008311171561046357600080fd5b91939092909160208101903564010000000081111561048157600080fd5b82018360208201111561049357600080fd5b803590602001918460018302840111640100000000831117156104b557600080fd5b509092509050610a46565b61023e610d97565b61023e610d9d565b610234610da3565b610234610e44565b610234610ec6565b6102fe600480360360208110156104fe57600080fd5b50356001600160a01b031661107f565b61023e61109d565b61028b6110a3565b6102fe6110a8565b61023e6110b1565b610537336110b7565b565b7388cb4d8f77742c24d647bef8049d3f3c56067cdd81565b606481565b61200181565b600181565b61100181565b6102ca81565b600881565b61200081565b6001600160a01b031660009081526007602052604090205460ff1690565b6001600160a01b031660009081526008602052604090205460ff1690565b61100581565b600281565b601081565b61100881565b3360009081526008602052604090205460ff166106185760405162461bcd60e51b81526004018080602001828103825260248152602001806115c36024913960400191505060405180910390fd5b61062133611219565b1561065d5760405162461bcd60e51b81526004018080602001828103825260218152602001806115806021913960400191505060405180910390fd5b3233146106b1576040805162461bcd60e51b815260206004820152601e60248201527f70726f766973696f6e616c2072656c6179657220697320612070726f78790000604482015290519081900360640190fd5b6001600160a01b038181166000908152600960205260409020541633146107095760405162461bcd60e51b815260040180806020018281038252602781526020018061163c6027913960400191505060405180910390fd5b6001600160a01b03818116600081815260066020908152604080832080543380865260078086528487208054600160ff199182161790915584546001600160a01b031990811684179095556008875285882080548216905597875260098652848720805490941690935596168085529083529281902080549094169093558251828152908101939093528151909260008051602061166383398151915292908290030190a15050565b600b81565b68056bc75e2d6310000081565b3360009081526005602052604090205460ff16610821576040805162461bcd60e51b81526020600482015260166024820152751b585b9859d95c88191bd95cc81b9bdd08195e1a5cdd60521b604482015290519081900360640190fd5b61082a81611219565b156108665760405162461bcd60e51b81526004018080602001828103825260278152602001806115e76027913960400191505060405180910390fd5b6001600160a01b03811615610922576001600160a01b03811660009081526007602052604090205460ff16156108dc576040805162461bcd60e51b815260206004820152601660248201527572656c6179657220616c72656164792065786973747360501b604482015290519081900360640190fd5b6001600160a01b0381166000818152600860209081526040808320805460ff191660011790553383526009909152902080546001600160a01b03191690911790556109c3565b3360008181526006602090815260408083208054600980855283862080546001600160a01b03198085169095556001600160a01b0393841680895260078852868920805460ff19908116909155918516808a5260088952878a20805490931690925598909752908552805490921690915581518581529086169281019290925280516000805160206116638339815191529281900390910190a15050610a00565b604080516001600160a01b038316815290517ffba56633276570c7d3120d4535bf3bce26523da53958e40734210b9fd99b36939181900360200190a15b50565b67016345785d8a000081565b600981565b61100781565b61100681565b7342d596440775c90db8d9187b47650986e106349381565b60005460ff1681565b600081565b60005460ff16610a99576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b3361100714610ad95760405162461bcd60e51b815260040180806020018281038252602e81526020018061160e602e913960400191505060405180910390fd5b610b3a84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600a81526930b23226b0b730b3b2b960b11b6020820152915061121f9050565b15610bd25760148114610b7e5760405162461bcd60e51b81526004018080602001828103825260228152602001806115a16022913960400191505060405180910390fd5b6000610bc1601484848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061130692505050565b9050610bcc8161130b565b50610d05565b610c3684848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600d81526c3932b6b7bb32a6b0b730b3b2b960991b6020820152915061121f9050565b15610cc85760148114610c7a5760405162461bcd60e51b81526004018080602001828103825260228152602001806115a16022913960400191505060405180910390fd5b6000610cbd601484848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061130692505050565b9050610bcc816110b7565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b61100281565b61100381565b600a5460ff1615610dfb576040805162461bcd60e51b815260206004820152601e60248201527f7468652077686974656c6973747320616c726561647920757064617465640000604482015290519081900360640190fd5b610e187388cb4d8f77742c24d647bef8049d3f3c56067cdd6113cd565b610e357342d596440775c90db8d9187b47650986e10634936113cd565b600a805460ff19166001179055565b60005460ff1615610e9c576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b68056bc75e2d63100000600190815567016345785d8a00006002556000805460ff19169091179055565b3360009081526004602052604090205460ff16610f21576040805162461bcd60e51b81526020600482015260146024820152731c995b185e595c88191bc81b9bdd08195e1a5cdd60621b604482015290519081900360640190fd5b60005460ff16610f74576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b610f7c611565565b5033600081815260036020908152604091829020825180840190935280548084526001909101549183018290529192916108fc91610fc0919063ffffffff61148516565b6040518115909202916000818181858888f19350505050158015610fe8573d6000803e3d6000fd5b50602081015160405161100291829181156108fc0291906000818181858888f1935050505015801561101e573d6000803e3d6000fd5b50336000818152600460209081526040808320805460ff191690556003825280832083815560010192909255815192835290517fd17202129b83db7880d6b9f25df81c58ad46f7e0e2c92236b1aa10663a4876679281900390910190a15050565b6001600160a01b031660009081526005602052604090205460ff1690565b61100081565b600381565b600a5460ff1681565b61100481565b6001600160a01b03811660009081526005602052604090205460ff1661111c576040805162461bcd60e51b81526020600482015260156024820152741b585b9859d95c88191bd95cdb89dd08195e1a5cdd605a1b604482015290519081900360640190fd5b6001600160a01b038082166000818152600660209081526040808320805460058452828520805460ff1990811690915582546001600160a01b0319908116909355600980865284872080548a16885260088752858820805490931690925595879052948452845490911690935580519384525191909316927f2002866d443ac6c241fecaaa2af4895828c7de2cc423b9d01f7969650f557c76928290030190a16001600160a01b03811615611215576001600160a01b0381166000818152600760209081526040808320805460ff1916905580519384529083019190915280516000805160206116638339815191529281900390910190a15b5050565b3b151590565b6000816040516020018082805190602001908083835b602083106112545780518252601f199092019160209182019101611235565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b602083106112c25780518252601f1990920191602091820191016112a3565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b015190565b6001600160a01b03811660009081526005602052604090205460ff1615611372576040805162461bcd60e51b81526020600482015260166024820152756d616e6167657220616c72656164792065786973747360501b604482015290519081900360640190fd5b6001600160a01b038116600081815260056020908152604091829020805460ff19166001179055815192835290517fe0de8e71a22c046647f4ef744348fa126ad6d052d4ce070999481f69d45575179281900390910190a150565b6001600160a01b03811660008181526005602090815260408083208054600160ff1991821681179092556006845282852080546001600160a01b031916871790556007845293829020805490941617909255815192835290517fe0de8e71a22c046647f4ef744348fa126ad6d052d4ce070999481f69d45575179281900390910190a160408051600081526001600160a01b03831660208201528151600080516020611663833981519152929181900390910190a150565b60006114c783836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506114ce565b9392505050565b6000818484111561155d5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561152257818101518382015260200161150a565b50505050905090810190601f16801561154f5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b60405180604001604052806000815260200160008152509056fe70726f766973696f6e616c2072656c61796572206973206120636f6e74726163746c656e677468206f66206d616e616765722061646472657373206d69736d6174636872656c61796572206973206e6f7420612070726f766973696f6e616c2072656c61796572636f6e7472616374206973206e6f7420616c6c6f77656420746f20626520612072656c61796572746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e747261637470726f766973696f6e616c206973206e6f742073657420666f722074686973206d616e61676572a5a19d7e9dab30a215022382d7abe782b579986fcbedec9942ecd0db9510a148a2646970667358221220243ef96c0e2d17d4e167cfcbcb6a51b4b92c1ac27fcb61400a87275f5128b4ab64736f6c63430006040033", + }, + { + ContractAddr: common.HexToAddress(CrossChainContract), + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/b144718e94d7a1ebb24a7103202300f08826f369", + Code: "608060405234801561001057600080fd5b50600436106103995760003560e01c8063718a8aa8116101e9578063c27cdcfb1161010f578063dc927faf116100ad578063f7a251d71161007c578063f7a251d714610b2f578063f9a2bbc714610ba7578063fc3e590814610baf578063fd6a687914610bb757610399565b8063dc927faf14610af7578063e1c7392a14610aff578063e3b0480514610b07578063e6400bbe14610b2757610399565b8063ccc108d7116100e9578063ccc108d714610ab0578063d31f968d14610ab8578063d76a867514610ae7578063dc40433114610aef57610399565b8063c27cdcfb14610a80578063c780e9de14610aa0578063c81b166214610aa857610399565b80638cc8f56111610187578063a78abc1611610156578063a78abc16146109b2578063ab51bb96146109ba578063ac431751146109c2578063b0355f5b1461078157610399565b80638cc8f5611461088757806396713da91461099a5780639dc09262146109a2578063a1a11bf5146109aa57610399565b806375d47a0a116101c357806375d47a0a146108a75780637942fd05146108af57806384013b6a146108b7578063863fe4ab1461099257610399565b8063718a8aa81461088f578063719482d51461089757806374f079b81461089f57610399565b8063422f9050116102ce57806363e1394e1161026c5780636de380bd1161023b5780636de380bd146108575780636e47a51a1461085f5780636e47b4821461087f57806370fd5bad1461088757610399565b806363e1394e146107ff5780636a3cb34d146108075780636bacff2c1461080f5780636c46aa681461080757610399565b80634bf6c882116102a85780634bf6c882146107b957806351e80672146107c15780635692ddd3146107c95780635f832177146107d157610399565b8063422f90501461078957806343756e5c146107a9578063493279b1146107b157610399565b8063299b533d1161033b578063308325f411610315578063308325f4146106155780633a648b151461061d5780633bdc47a6146106595780633dffc3871461078157610399565b8063299b533d146105a35780632af6f399146105d75780632ff32aea146105f457610399565b806314b3023b1161037757806314b3023b146104015780631d1309351461041b5780631e275ae11461043757806322556cdc1461059b57610399565b806305e682581461039e5780630bee7a67146103bc5780630e2374a5146103dd575b600080fd5b6103a6610bbf565b6040805160ff9092168252519081900360200190f35b6103c4610bc4565b6040805163ffffffff9092168252519081900360200190f35b6103e5610bc9565b604080516001600160a01b039092168252519081900360200190f35b610409610bcf565b60408051918252519081900360200190f35b610423610bd5565b604080519115158252519081900360200190f35b610599600480360361010081101561044e57600080fd5b81018160a081016080820135600160201b81111561046b57600080fd5b82018360208201111561047d57600080fd5b803590602001918460018302840111600160201b8311171561049e57600080fd5b919390929091602081019035600160201b8111156104bb57600080fd5b8201836020820111156104cd57600080fd5b803590602001918460018302840111600160201b831117156104ee57600080fd5b919390929091602081019035600160201b81111561050b57600080fd5b82018360208201111561051d57600080fd5b803590602001918460018302840111600160201b8311171561053e57600080fd5b919390929091602081019035600160201b81111561055b57600080fd5b82018360208201111561056d57600080fd5b803590602001918460018302840111600160201b8311171561058e57600080fd5b509092509050610bde565b005b6104096112c2565b6105c0600480360360208110156105b957600080fd5b50356112c7565b6040805161ffff9092168252519081900360200190f35b610423600480360360208110156105ed57600080fd5b50356112dd565b6105fc6112f2565b60408051600792830b90920b8252519081900360200190f35b6104096112fb565b61063d6004803603602081101561063357600080fd5b503560ff16611301565b604080516001600160401b039092168252519081900360200190f35b61070c6004803603606081101561066f57600080fd5b60ff82351691602081013591810190606081016040820135600160201b81111561069857600080fd5b8201836020820111156106aa57600080fd5b803590602001918460018302840111600160201b831117156106cb57600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061131c945050505050565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561074657818101518382015260200161072e565b50505050905090810190601f1680156107735780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6103a6611392565b6104236004803603602081101561079f57600080fd5b503560ff16611397565b6103e56113ac565b6105c06113b2565b6103a66113b8565b6103e56113bd565b6104096113c3565b610599600480360360408110156107e757600080fd5b506001600160a01b03813581169160200135166113f3565b610409611653565b6105c061167b565b61082c6004803603602081101561082557600080fd5b5035611680565b6040805161ffff90941684526001600160801b03909216602084015282820152519081900360600190f35b6104096116af565b6103e56004803603602081101561087557600080fd5b503560ff166116d6565b6103e56116f1565b6103a661167b565b6103a66116f7565b6105c0611392565b6104096116fc565b6103e5611702565b6103a6611708565b610599600480360360a08110156108cd57600080fd5b810190602081018135600160201b8111156108e757600080fd5b8201836020820111156108f957600080fd5b803590602001918460018302840111600160201b8311171561091a57600080fd5b919390929091602081019035600160201b81111561093757600080fd5b82018360208201111561094957600080fd5b803590602001918460018302840111600160201b8311171561096a57600080fd5b919350915080356001600160401b03908116916020810135909116906040013560ff1661170d565b6104096129c7565b6103a66129cf565b6103e56129d4565b6103e56129da565b6104236129e0565b6103c4610bbf565b610599600480360360408110156109d857600080fd5b810190602081018135600160201b8111156109f257600080fd5b820183602082011115610a0457600080fd5b803590602001918460018302840111600160201b83111715610a2557600080fd5b919390929091602081019035600160201b811115610a4257600080fd5b820183602082011115610a5457600080fd5b803590602001918460018302840111600160201b83111715610a7557600080fd5b5090925090506129e9565b61063d60048036036020811015610a9657600080fd5b503560ff166134ad565b6104096134c8565b6103e56134ec565b6105996134f2565b61042360048036036040811015610ace57600080fd5b5080356001600160a01b0316906020013560ff16613746565b61070c613766565b610409613785565b6103e561378b565b610599613791565b61063d60048036036020811015610b1d57600080fd5b503560ff16613b48565b610599613b63565b61059960048036036060811015610b4557600080fd5b60ff8235169190810190604081016020820135600160201b811115610b6957600080fd5b820183602082011115610b7b57600080fd5b803590602001918460018302840111600160201b83111715610b9c57600080fd5b919350915035613d82565b6103e5613ec5565b6103a6613ecb565b6103e5613ed0565b600081565b606481565b61200181565b60015481565b600b5460ff1681565b60005460ff16610c23576040805162461bcd60e51b815260206004820152601960248201526000805160206149b4833981519152604482015290519081900360640190fd5b604080516337d7f9c160e21b81526001600160401b038b35166004820181905291516110039163df5fe704916024808301926020929190829003018186803b158015610c6e57600080fd5b505afa158015610c82573d6000803e3d6000fd5b505050506040513d6020811015610c9857600080fd5b5051610cd55760405162461bcd60e51b81526004018080602001828103825260238152602001806149d46023913960400191505060405180910390fd5b604080516337d7f9c160e21b815260208c8101356001600160401b03166004830181905292516110039263df5fe704926024808301939192829003018186803b158015610d2157600080fd5b505afa158015610d35573d6000803e3d6000fd5b505050506040513d6020811015610d4b57600080fd5b5051610d885760405162461bcd60e51b81526004018080602001828103825260238152602001806149d46023913960400191505060405180910390fd5b60608b013560ff81166000908152600560205260409020546001600160401b03909116906001600160a01b0316610e01576040805162461bcd60e51b815260206004820152601860248201527718da185b9b995b081a5cc81b9bdd081cdd5c1c1bdc9d195960421b604482015290519081900360640190fd5b600b5460ff1615610e45576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b8888604051808383808284376040519201829003822094508f93508e9250819050838380828437808301925050509250505060405180910390201415610ec1576040805162461bcd60e51b815260206004820152600c60248201526b1cd85b59481c185e5b1bd85960a21b604482015290519081900360640190fd5b60606001600160401b0360408e01358116908e83013516610ee28282613ed6565b80516020808301919091206000818152600e9092526040909120549194509060ff1615610f4b576040805162461bcd60e51b8152602060048201526012602482015271185b1c9958591e4818da185b1b195b99d95960721b604482015290519081900360640190fd5b6000908152600e60205260408120805460ff191660011790558f8160200201356001600160401b0316905060608f8f8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050905060608c8c8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052506040805163cba510a960e01b81526001600160401b038a16600482015290519596509094611003945063cba510a9935060248083019350602092829003018186803b15801561104157600080fd5b505afa158015611055573d6000803e3d6000fd5b505050506040513d602081101561106b57600080fd5b505160408051808201909152600381526269626360e81b6020820152909150611098908290898686613f1e565b6110e1576040805162461bcd60e51b81526020600482015260156024820152740696e76616c6964206d65726b6c652070726f6f663605c1b604482015290519081900360640190fd5b5050505060008f6001600481106110f457fe5b60200201356001600160401b0316905060608d8d8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8f018190048102820181019092528d815293945060609392508d91508c908190840183828082843760009201829052506040805163cba510a960e01b81526001600160401b038a16600482015290519596509094611003945063cba510a9935060248083019350602092829003018186803b1580156111c057600080fd5b505afa1580156111d4573d6000803e3d6000fd5b505050506040513d60208110156111ea57600080fd5b505160408051808201909152600381526269626360e81b6020820152909150611217908290898686613f1e565b611260576040805162461bcd60e51b8152602060048201526015602482015274696e76616c6964206d65726b6c652070726f6f663160581b604482015290519081900360640190fd5b5050505061126c61401b565b604080516001600160401b038416815260ff83166020820152815133927f039eb91179ffd7d3b6e97f8ea106e748e827f910b872375dbc9c14a362319c3c928290030190a2505050505050505050505050505050565b603281565b600d6020526000908152604090205461ffff1681565b600e6020526000908152604090205460ff1681565b60045460070b81565b60025481565b600a602052600090815260409020546001600160401b031681565b60606000825160210190506060816040519080825280601f01601f191660200182016040528015611354576020820181803683370190505b506021810186905260018101879052828152905060418101600061137786614099565b509050611386818388516140a3565b50909695505050505050565b600181565b60096020526000908152604090205460ff1681565b61100181565b6102ca81565b600881565b61200081565b604080517710d05390d15317d514905394d1915497d41493d413d4d05360421b8152905190819003601801902081565b60005460ff16611438576040805162461bcd60e51b815260206004820152601960248201526000805160206149b4833981519152604482015290519081900360640190fd5b6040805163569e4ed360e11b815233600482015290516000916110009163ad3c9da691602480820192602092909190829003018186803b15801561147b57600080fd5b505afa15801561148f573d6000803e3d6000fd5b505050506040513d60208110156114a557600080fd5b505160408051633d42651560e11b8152905191925060009161100091637a84ca2a916004808301926020929190829003018186803b1580156114e657600080fd5b505afa1580156114fa573d6000803e3d6000fd5b505050506040513d602081101561151057600080fd5b505190508061151d575060155b60008211801561152d5750808211155b61156c576040805162461bcd60e51b815260206004820152600b60248201526a1b9bdd0818d8589a5b995d60aa1b604482015290519081900360640190fd5b604080516001600160a01b038087166020808401919091529086168284015282518083038401815260608301808552815191909201207710d05390d15317d514905394d1915497d41493d413d4d05360421b90915291519081900360780190206000906115d990836140e4565b9050801561164b5760408051630911a2c160e11b81526001600160a01b03888116600483015287166024820152905161100491631223458291604480830192600092919082900301818387803b15801561163257600080fd5b505af1158015611646573d6000803e3d6000fd5b505050505b505050505050565b604080516f14d554d411539117d41493d413d4d05360821b8152905190819003601001902081565b600281565b600c602052600090815260409020805460019091015461ffff8216916201000090046001600160801b03169083565b604080516e149153d4115397d41493d413d4d053608a1b8152905190819003600f01902081565b6005602052600090815260409020546001600160a01b031681565b61100581565b601081565b60035481565b61100881565b600b81565b60005460ff16611752576040805162461bcd60e51b815260206004820152601960248201526000805160206149b4833981519152604482015290519081900360640190fd5b60408051630a83aaa960e31b815233600482015290516110069163541d5548916024808301926020929190829003018186803b15801561179157600080fd5b505afa1580156117a5573d6000803e3d6000fd5b505050506040513d60208110156117bb57600080fd5b505161180e576040805162461bcd60e51b815260206004820152601f60248201527f746865206d73672073656e646572206973206e6f7420612072656c6179657200604482015290519081900360640190fd5b60ff8116600090815260086020526040902054829082906001600160401b03908116908316811461187e576040805162461bcd60e51b815260206004820152601560248201527439b2b8bab2b731b2903737ba1034b71037b93232b960591b604482015290519081900360640190fd5b60ff8216600090815260086020908152604091829020805467ffffffffffffffff1916600185016001600160401b039081169190911790915582516337d7f9c160e21b81529089166004820152915188926110039263df5fe70492602480840193829003018186803b1580156118f357600080fd5b505afa158015611907573d6000803e3d6000fd5b505050506040513d602081101561191d57600080fd5b505161195a5760405162461bcd60e51b81526004018080602001828103825260238152602001806149d46023913960400191505060405180910390fd5b60ff851660009081526005602052604090205485906001600160a01b03166119c4576040805162461bcd60e51b815260206004820152601860248201527718da185b9b995b081a5cc81b9bdd081cdd5c1c1bdc9d195960421b604482015290519081900360640190fd5b60ff86166000908152600a6020526040902054889087906001600160401b039081169083161015611a2d576040805162461bcd60e51b815260206004820152600e60248201526d3a37b79037b632103432b0b232b960911b604482015290519081900360640190fd5b60ff81166000908152600a60205260409020546001600160401b03838116911614611a7f5760ff81166000908152600a60205260409020805467ffffffffffffffff19166001600160401b0384161790555b600b5460ff1615611ac3576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b60608e8e8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050905060608d8d8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509050611c076110036001600160a01b031663cba510a98e6040518263ffffffff1660e01b815260040180826001600160401b03166001600160401b0316815260200191505060206040518083038186803b158015611bb057600080fd5b505afa158015611bc4573d6000803e3d6000fd5b505050506040513d6020811015611bda57600080fd5b505160408051808201909152600381526269626360e81b6020820152611c008e8e613ed6565b8585613f1e565b611c4f576040805162461bcd60e51b815260206004820152601460248201527334b73b30b634b21036b2b935b63290383937b7b360611b604482015290519081900360640190fd5b60408051631bb5062960e31b81526001600160401b038e16600482015290516000916110039163dda8314891602480820192602092909190829003018186803b158015611c9b57600080fd5b505afa158015611caf573d6000803e3d6000fd5b505050506040513d6020811015611cc557600080fd5b505190508b8b600080806060611cda896143c9565b935093509350935083611d9c578460ff16866001600160401b03167ff7b2e42d694eb1100184aae86d4245d9e46966100b1dc7e723275b98326854ac8b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015611d54578181015183820152602001611d3c565b50505050905090810190601f168015611d815780820380516001836020036101000a031916815260200191505b509250505060405180910390a35050505050505050506129b7565b6040805160ff85811682529151918716916001600160401b038916917f36afdaf439a8f43fe72135135d804ae620b37a474f0943b5b85f6788312cad40919081900360200190a360ff83166123215760ff85166000818152600560209081526040808320548151631182b87560e01b815260048101958652602481019283528651604482015286516001600160a01b03909216958695631182b875958d958a9593949093606490910192918601918190849084905b83811015611e69578181015183820152602001611e51565b50505050905090810190601f168015611e965780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b158015611eb657600080fd5b505af1925050508015611f9a57506040513d6000823e601f3d908101601f191682016040526020811015611ee957600080fd5b8101908080516040519392919084600160201b821115611f0857600080fd5b908301906020820185811115611f1d57600080fd5b8251600160201b811182820188101715611f3657600080fd5b82525081516020918201929091019080838360005b83811015611f63578181015183820152602001611f4b565b50505050905090810190601f168015611f905780820380516001836020036101000a031916815260200191505b5060405250505060015b6122ac576040516000815260443d1015611fb657506000612051565b60046000803e60005160e01c6308c379a08114611fd7576000915050612051565b60043d036004833e81513d60248201116001600160401b038211171561200257600092505050612051565b80830180516001600160401b03811115612023576000945050505050612051565b8060208301013d860181111561204157600095505050505050612051565b601f01601f191660405250925050505b8061205c575061216e565b60ff8716600090815260076020526040812054612093916001600160401b0390911690899061208e906002908861131c565b614479565b60ff8716600090815260076020908152604080832080546001600160401b038082166001011667ffffffffffffffff19909116179055805182815284518184015284516001600160a01b038716947ff91a8f63e5b3e0e89e5f93e1915a7805f3c52d9a73b3c09769785c2c7bf87acf948794849390840192918601918190849084905b8381101561212e578181015183820152602001612116565b50505050905090810190601f16801561215b5780820380516001836020036101000a031916815260200191505b509250505060405180910390a2506122a7565b3d808015612198576040519150601f19603f3d011682016040523d82523d6000602084013e61219d565b606091505b5060ff87166000908152600760205260408120546121d0916001600160401b0390911690899061208e906002908861131c565b60ff8716600090815260076020908152604080832080546001600160401b038082166001011667ffffffffffffffff19909116179055805182815284518184015284516001600160a01b038716947f63ac299d6332d1cc4e61b81e59bc00c0ac7c798addadf33840f1307cd2977351948794849390840192918601918190849084905b8381101561226b578181015183820152602001612253565b50505050905090810190601f1680156122985780820380516001836020036101000a031916815260200191505b509250505060405180910390a2505b61231b565b8051156123195760ff87166000908152600760205260408120546122e5916001600160401b0390911690899061208e906001908661131c565b60ff8716600090815260076020526040902080546001600160401b038082166001011667ffffffffffffffff199091161790555b505b506128ef565b60ff8316600114156125c55760ff8516600081815260056020908152604080832054815163831d65d160e01b815260048101958652602481019283528651604482015286516001600160a01b0390921695869563831d65d1958d958a9593949093606490910192918601918190849084905b838110156123ab578181015183820152602001612393565b50505050905090810190601f1680156123d85780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b1580156123f857600080fd5b505af1925050508015612409575060015b61231b576040516000815260443d1015612425575060006124c0565b60046000803e60005160e01c6308c379a081146124465760009150506124c0565b60043d036004833e81513d60248201116001600160401b0382111715612471576000925050506124c0565b80830180516001600160401b038111156124925760009450505050506124c0565b8060208301013d86018111156124b0576000955050505050506124c0565b601f01601f191660405250925050505b806124cb5750612530565b60408051602080825283518183015283516001600160a01b038616937ff91a8f63e5b3e0e89e5f93e1915a7805f3c52d9a73b3c09769785c2c7bf87acf938693909283928301918501908083836000831561212e578181015183820152602001612116565b3d80801561255a576040519150601f19603f3d011682016040523d82523d6000602084013e61255f565b606091505b5060408051602080825283518183015283516001600160a01b038616937f63ac299d6332d1cc4e61b81e59bc00c0ac7c798addadf33840f1307cd2977351938693909283928301918501908083836000831561226b578181015183820152602001612253565b60ff8316600214156128ef5760ff8516600081815260056020908152604080832054815163c8509d8160e01b815260048101958652602481019283528651604482015286516001600160a01b0390921695869563c8509d81958d958a9593949093606490910192918601918190849084905b8381101561264f578181015183820152602001612637565b50505050905090810190601f16801561267c5780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b15801561269c57600080fd5b505af19250505080156126ad575060015b6128ed576040516000815260443d10156126c957506000612764565b60046000803e60005160e01c6308c379a081146126ea576000915050612764565b60043d036004833e81513d60248201116001600160401b038211171561271557600092505050612764565b80830180516001600160401b03811115612736576000945050505050612764565b8060208301013d860181111561275457600095505050505050612764565b601f01601f191660405250925050505b8061276f5750612818565b816001600160a01b03167ff91a8f63e5b3e0e89e5f93e1915a7805f3c52d9a73b3c09769785c2c7bf87acf826040518080602001828103825283818151815260200191508051906020019080838360005b838110156127d85781810151838201526020016127c0565b50505050905090810190601f1680156128055780820380516001836020036101000a031916815260200191505b509250505060405180910390a2506128ed565b3d808015612842576040519150601f19603f3d011682016040523d82523d6000602084013e612847565b606091505b50816001600160a01b03167f63ac299d6332d1cc4e61b81e59bc00c0ac7c798addadf33840f1307cd2977351826040518080602001828103825283818151815260200191508051906020019080838360005b838110156128b1578181015183820152602001612899565b50505050905090810190601f1680156128de5780820380516001836020036101000a031916815260200191505b509250505060405180910390a2505b505b60ff80861660009081526009602052604090205461100591636f93d2e6918a91339187911680612921575060ff881615155b604080516001600160e01b031960e088901b1681526001600160a01b039586166004820152939094166024840152604483019190915215156064820152905160848083019260209291908290030181600087803b15801561298157600080fd5b505af1158015612995573d6000803e3d6000fd5b505050506040513d60208110156129ab57600080fd5b50505050505050505050505b5050505050505050505050505050565b630102ca0081565b600981565b61100781565b61100681565b60005460ff1681565b3361100714612a295760405162461bcd60e51b815260040180806020018281038252602e81526020018061490a602e913960400191505060405180910390fd5b600b5460ff1615612a6d576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b612ad684848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526012815271626174636853697a65466f724f7261636c6560701b602082015291506146149050565b15612b7157604080516020601f8401819004810282018101909252828152600091612b19918585808385018382808284376000920191909152506146fb92505050565b90506127108111158015612b2e5750600a8110155b612b695760405162461bcd60e51b81526004018080602001828103825260328152602001806149826032913960400191505060405180910390fd5b60015561341b565b612bda84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601281527118591913dc955c19185d1950da185b9b995b60721b602082015291506146149050565b15612d6257606082828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505082519293505060169091149050612c5d5760405162461bcd60e51b815260040180806020018281038252605a815260200180614823605a913960600191505060405180910390fd5b60018101516002820151601683015160ff82161590612c7b81614700565b612ccc576040805162461bcd60e51b815260206004820152601960248201527f61646472657373206973206e6f74206120636f6e747261637400000000000000604482015290519081900360640190fd5b60ff8416600081815260056020908152604080832080546001600160a01b0319166001600160a01b038716908117909155808452600683528184208585528352818420805460ff199081166001179091556009909352818420805490931687151517909255519092917f7e3b6af43092577ee20e60eaa1d9b114a7031305c895ee7dd3ffe17196d2e1e091a3505050505061341b565b612dcf84848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526016815275195b98589b1953dc911a5cd8589b1950da185b9b995b60521b602082015291506146149050565b15612f0057606082828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505082519293505060029091149050612e525760405162461bcd60e51b815260040180806020018281038252604a815260200180614938604a913960600191505060405180910390fd5b600181810151600283015160ff80831660009081526005602052604090205492939192908316909114906001600160a01b03168015612ef6576001600160a01b038116600090815260066020908152604080832060ff881680855290835292819020805460ff1916861515908117909155815190815290517fa3132e3f9819fbddc7f0ed6d38d7feef59aa95112090b7c592f5cb5bc4aa4adc929181900390910190a25b505050505061341b565b612f6484848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600d81526c73757370656e6451756f72756d60981b602082015291506146149050565b156130995760028114612fa85760405162461bcd60e51b815260040180806020018281038252602d8152602001806148b1602d913960400191505060405180910390fd5b6000612feb600284848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506146fb92505050565b905060008161ffff16118015613005575060648161ffff16105b61304f576040805162461bcd60e51b8152602060048201526016602482015275696e76616c69642073757370656e642071756f72756d60501b604482015290519081900360640190fd5b604080516f14d554d411539117d41493d413d4d05360821b815281519081900360100190206000908152600d60205220805461ffff90921661ffff1990921691909117905561341b565b6130fc84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600c81526b72656f70656e51756f72756d60a01b602082015291506146149050565b1561322f57600281146131405760405162461bcd60e51b815260040180806020018281038252602c8152602001806148de602c913960400191505060405180910390fd5b6000613183600284848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506146fb92505050565b905060008161ffff1611801561319d575060648161ffff16105b6131e6576040805162461bcd60e51b8152602060048201526015602482015274696e76616c69642072656f70656e2071756f72756d60581b604482015290519081900360640190fd5b604080516e149153d4115397d41493d413d4d053608a1b8152815190819003600f0190206000908152600d60205220805461ffff90921661ffff1990921691909117905561341b565b61329a84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601481527363616e63656c5472616e7366657251756f72756d60601b602082015291506146149050565b156133de57600281146132de5760405162461bcd60e51b815260040180806020018281038252603481526020018061487d6034913960400191505060405180910390fd5b6000613321600284848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506146fb92505050565b905060008161ffff1611801561333b575060648161ffff16105b61338c576040805162461bcd60e51b815260206004820152601e60248201527f696e76616c69642063616e63656c207472616e736665722071756f72756d0000604482015290519081900360640190fd5b604080517710d05390d15317d514905394d1915497d41493d413d4d05360421b815281519081900360180190206000908152600d60205220805461ffff90921661ffff1990921691909117905561341b565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b6008602052600090815260409020546001600160401b031681565b7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081565b61100281565b60005460ff16613537576040805162461bcd60e51b815260206004820152601960248201526000805160206149b4833981519152604482015290519081900360640190fd5b6040805163569e4ed360e11b815233600482015290516000916110009163ad3c9da691602480820192602092909190829003018186803b15801561357a57600080fd5b505afa15801561358e573d6000803e3d6000fd5b505050506040513d60208110156135a457600080fd5b505160408051633d42651560e11b8152905191925060009161100091637a84ca2a916004808301926020929190829003018186803b1580156135e557600080fd5b505afa1580156135f9573d6000803e3d6000fd5b505050506040513d602081101561360f57600080fd5b505190508061361c575060155b60008211801561362c5750808211155b61366b576040805162461bcd60e51b815260206004820152600b60248201526a1b9bdd0818d8589a5b995d60aa1b604482015290519081900360640190fd5b600b5460ff166136b2576040805162461bcd60e51b815260206004820152600d60248201526c1b9bdd081cdd5cdc195b991959609a1b604482015290519081900360640190fd5b604080516e149153d4115397d41493d413d4d053608a1b8152905190819003600f019020600090613703907fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4706140e4565b9050801561374157600b805460ff1916905560405133907f899fe8c37dc61708a3aaa99c4bf143346c1d1da69af79be9e8920c0a6785b75290600090a25b505050565b600660209081526000928352604080842090915290825290205460ff1681565b6040518060400160405280600381526020016269626360e81b81525081565b610e1081565b61100381565b60005460ff16156137e9576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b7f1471eb6eb2c5e789fc3de43f8ce62938c7d1836ec861730447e2ada8fd81017b80546001600160a01b0319908116611008179091557f92e85d02570a8092d09a6e3a57665bc3815a2699a4074001bf1ccabf660f5a36805460ff199081169091557fd8af288fc1c8680b4f4706064cf021e264efb6828fcaf7eb5ca36818eb365bcc8054821660019081179091557f89832631fb3c3307a103ba2c84ab569c64d6182a18893dcd163f0f1c2090733a805484166110049081179091557f6cde3cea4b3a3fb2488b2808bae7556f4a405e50f65e1794383bc026131b13c38054841690557f72e4efa1513b071517c6c74dba31b5934a81aa83cddd400e7081df5529c9943680548416831790557fa9bc9a3a348c357ba16b37005d7e6b3236198c0e939f4af8c5f19b8deeb8ebc08054851690911790557fc575c31fea594a6eb97c8e9d3f9caee4c16218c6ef37e923234c0fe9014a61e78054831690557f4e523af77f034e9810f1c94057f5e931fb3d16a51511a4c3add793617d18610580548316821790557ffb33122aa9f93cc639ebe80a7bc4784c11e6053dde89c6f4f7e268c6a623da1e805484166110001790557fc7694af312c4f286114180fd0ba6a52461fcee8a381636770b19a343af92538a80548316821790557f01112dd68e482ba8d68a7e828cff8b3abcea08eab88941953c180a7e650e9cd480548316821790557fc0a4a8be475dfebc377ebef2d7c4ff47656f572a08dd92b81017efcdba0febe1805484166110071790557f87e8a52529e8ece4ef759037313542a6429ff494a9fab9027fb79db90124eba680548316821790557f4c7666bbcb22d46469f7cc282f70764a7012dca2cce630ff8d83db9a9cdd48f080548316821790557f40f28f99a40bc9f6beea1013afdbc3cdcc689eb76b82c4de06c0acf1e1932ed58054909316611001179092557f0d9cf2cd531699eed8dd34e40ff2884a14a698c4898184fba85194e6f6772d248054821683179055600b60009081527f23f68c9bd22b8a93d06adabe17481c87c016bcbd20adc8bfd707a4d813a572176020527fdf0d5d05428057f5455c2dc8e810dd86d1e9350faa72f16bda8a45443c5b39328054831684179055603283556004805467ffffffffffffffff19166001600160401b031790556002819055600381905580549091169091179055565b6007602052600090815260409020546001600160401b031681565b60005460ff16613ba8576040805162461bcd60e51b815260206004820152601960248201526000805160206149b4833981519152604482015290519081900360640190fd5b6040805163569e4ed360e11b815233600482015290516000916110009163ad3c9da691602480820192602092909190829003018186803b158015613beb57600080fd5b505afa158015613bff573d6000803e3d6000fd5b505050506040513d6020811015613c1557600080fd5b505160408051633d42651560e11b8152905191925060009161100091637a84ca2a916004808301926020929190829003018186803b158015613c5657600080fd5b505afa158015613c6a573d6000803e3d6000fd5b505050506040513d6020811015613c8057600080fd5b5051905080613c8d575060155b600082118015613c9d5750808211155b613cdc576040805162461bcd60e51b815260206004820152600b60248201526a1b9bdd0818d8589a5b995d60aa1b604482015290519081900360640190fd5b600b5460ff1615613d20576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b604080516f14d554d411539117d41493d413d4d05360821b81529051908190036010019020600090613d72907fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4706140e4565b905080156137415761374161401b565b60005460ff16613dc7576040805162461bcd60e51b815260206004820152601960248201526000805160206149b4833981519152604482015290519081900360640190fd5b33600090815260066020908152604080832060ff8089168552925290912054859116613e245760405162461bcd60e51b81526004018080602001828103825260318152602001806147f26031913960400191505060405180910390fd5b60ff85166000908152600760209081526040808320548151601f88018490048402810184019092528682526001600160401b031692613e899284928a9261208e92909189918c908c908190840183828082843760009201919091525061131c92505050565b60ff959095166000908152600760205260409020805467ffffffffffffffff191660019096016001600160401b03169590951790945550505050565b61100081565b600381565b61100481565b60408051600e808252818301909252606091630102ca0060ff851617918391602082018180368337505050600e81810187905260068201939093529182525090505b92915050565b600085613f2d57506000614012565b606082518451865160800101016040519080825280601f01601f191660200182016040528015613f64576020820181803683370190505b5090506000613f7282614706565b602080890151825201905086600080613f8a89614099565b8086526020909501949092509050613fa38285836140a3565b92830192613fb088614099565b8086526020909501949092509050613fc98285836140a3565b9283018a815260200192613fdc87614099565b9092509050613fec8285836140a3565b508351602001613ffa61470c565b60208183886065600019fa5051600114955050505050505b95945050505050565b600b5460ff161561405f576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b600b805460ff1916600117905560405133907f6f123d3d54c84a7960a573b31c221dcd86e13fd849c5adb0c6ca851468cc1ae490600090a2565b8051602090910191565b5b602081106140c3578251825260209283019290910190601f19016140a4565b915181516020939093036101000a6000190180199091169216919091179052565b6000828152600d602052604081205461ffff166141ad57604080516f14d554d411539117d41493d413d4d05360821b815281519081900360100181206000908152600d6020818152848320805461ffff199081166001179091556e149153d4115397d41493d413d4d053608a1b8552855194859003600f01852084528282528584208054821660029081179091557710d05390d15317d514905394d1915497d41493d413d4d05360421b8652865195869003601801909520845291905292902080549092161790555b6000838152600c6020526040902080546201000090046001600160801b0316421015806141de575082816001015414155b156142b1576000848152600d602090815260409182902054835461ffff90911661ffff199091161771ffffffffffffffffffffffffffffffff0000191662010000610e1042016001600160801b031602178355600180840186905582519182019092523381526142539160028401919061472a565b5080546040805161ffff83168152620100009092046001600160801b0316602083015281810185905251339186917f9e109f0e55ef32e99e4880be2ec357f1ddb3469c79d0747ef4762da6e89fabe5916060908290030190a3614365565b60005b600282015481101561433c57336001600160a01b03168260020182815481106142d957fe5b6000918252602090912001546001600160a01b03161415614334576040805162461bcd60e51b815260206004820152601060248201526f185b1c9958591e48185c1c1c9bdd995960821b604482015290519081900360640190fd5b6001016142b4565b50600281018054600181018255600091825260209091200180546001600160a01b031916331790555b8054600282015461ffff909116116143bf576000848152600c60205260408120805471ffffffffffffffffffffffffffffffffffff1916815560018101829055906143b3600283018261478f565b50506001915050613f18565b5060009392505050565b600080600060606021855110156143f9575050604080516000808252602082019092529092508291508190614472565b600185015160218601518651604080516020198301808252601f1960011990940193909316810160200190915260418901939291606091908015614444576020820181803683370190505b509050600061445282614099565b509050614464858260218d51036140a3565b506001975091955093509150505b9193509193565b600b5460ff16156144bd576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b6002544311156144fc576004805467ffffffffffffffff1981166001600160401b036001600793840b810190930b16179091556003554360025561453d565b6003805460019081019182905554101561453d576004805467ffffffffffffffff1981166001600160401b036001600793840b810190930b16179091556003555b8160ff16836001600160401b0316600460009054906101000a900460070b6001600160401b03167f3a6e0fc61675aa2a100bcba0568368bb92bcec91c97673391074f11138f0cffe6102ca85604051808361ffff1661ffff16815260200180602001828103825283818151815260200191508051906020019080838360005b838110156145d45781810151838201526020016145bc565b50505050905090810190601f1680156146015780820380516001836020036101000a031916815260200191505b50935050505060405180910390a4505050565b6000816040516020018082805190602001908083835b602083106146495780518252601f19909201916020918201910161462a565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b602083106146b75780518252601f199092019160209182019101614698565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b015190565b3b151590565b60200190565b60405180602001604052806001906020820280368337509192915050565b82805482825590600052602060002090810192821561477f579160200282015b8281111561477f57825182546001600160a01b0319166001600160a01b0390911617825560209092019160019091019061474a565b5061478b9291506147b0565b5090565b50805460008255906000526020600020908101906147ad91906147d7565b50565b6147d491905b8082111561478b5780546001600160a01b03191681556001016147b6565b90565b6147d491905b8082111561478b57600081556001016147dd56fe74686520636f6e747261637420616e64206368616e6e656c2068617665206e6f74206265656e20726567697374657265646c656e677468206f662076616c756520666f72206164644f725570646174654368616e6e656c2073686f756c642062652032322c206368616e6e656c49643a697346726f6d53797374656d3a68616e646c6572416464726573736c656e677468206f662076616c756520666f722063616e63656c5472616e7366657251756f72756d2073686f756c6420626520326c656e677468206f662076616c756520666f722073757370656e6451756f72756d2073686f756c6420626520326c656e677468206f662076616c756520666f722072656f70656e51756f72756d2073686f756c642062652032746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e74726163746c656e677468206f662076616c756520666f7220656e61626c654f7244697361626c654368616e6e656c2073686f756c6420626520322c206368616e6e656c49643a6973456e61626c65746865206e6577426174636853697a65466f724f7261636c652073686f756c6420626520696e205b31302c2031303030305d74686520636f6e7472616374206e6f7420696e697420796574000000000000006c6967687420636c69656e74206e6f742073796e632074686520626c6f636b20796574a264697066735822122020f10a3f6af250b9c5c16c5020f1b83db8bc64ed4363d8712e2b85f20f56251164736f6c63430006040033", + }, + }, + } } func UpgradeBuildInSystemContract(config *params.ChainConfig, blockNumber *big.Int, statedb *state.StateDB) { @@ -603,6 +697,10 @@ func UpgradeBuildInSystemContract(config *params.ChainConfig, blockNumber *big.I applySystemContractUpgrade(planckUpgrade[network], blockNumber, statedb, logger) } + if config.IsOnLuban(blockNumber) { + applySystemContractUpgrade(lubanUpgrade[network], blockNumber, statedb, logger) + } + /* apply other upgrades */ diff --git a/core/types/vote.go b/core/types/vote.go new file mode 100644 index 0000000000..e631b7294d --- /dev/null +++ b/core/types/vote.go @@ -0,0 +1,92 @@ +package types + +import ( + "sync/atomic" + + "github.com/pkg/errors" + "github.com/prysmaticlabs/prysm/v3/crypto/bls" + + "github.com/ethereum/go-ethereum/common" +) + +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 common.Hash // The block hash of the source block. + TargetNumber uint64 // The target block number which validator wants to vote for. + TargetHash common.Hash // The block hash of the target block. +} + +// Hash returns the hash of the vote data. +func (d *VoteData) Hash() common.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() common.Hash { + if hash := v.hash.Load(); hash != nil { + return hash.(common.Hash) + } + + h := v.calcVoteHash() + v.hash.Store(h) + return h +} + +func (v *VoteEnvelope) calcVoteHash() common.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 d0f3a1ba03..acdf9e7cfb 100644 --- a/core/vm/contracts.go +++ b/core/vm/contracts.go @@ -22,16 +22,17 @@ import ( "errors" "math/big" + "github.com/prysmaticlabs/prysm/v3/crypto/bls" + "golang.org/x/crypto/ripemd160" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/math" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto/blake2b" "github.com/ethereum/go-ethereum/crypto/bls12381" "github.com/ethereum/go-ethereum/crypto/bn256" + "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" - - //lint:ignore SA1019 Needed for precompile - "golang.org/x/crypto/ripemd160" ) // PrecompiledContract is the basic interface for native Go contracts. The implementation @@ -140,6 +141,25 @@ var PrecompiledContractsBerlin = map[common.Address]PrecompiledContract{ common.BytesToAddress([]byte{9}): &blake2F{}, } +// PrecompiledContractsLuban contains the default set of pre-compiled Ethereum +// contracts used in the Luban release. +var PrecompiledContractsLuban = map[common.Address]PrecompiledContract{ + common.BytesToAddress([]byte{1}): &ecrecover{}, + common.BytesToAddress([]byte{2}): &sha256hash{}, + common.BytesToAddress([]byte{3}): &ripemd160hash{}, + common.BytesToAddress([]byte{4}): &dataCopy{}, + common.BytesToAddress([]byte{5}): &bigModExp{}, + common.BytesToAddress([]byte{6}): &bn256AddIstanbul{}, + common.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{}, + common.BytesToAddress([]byte{8}): &bn256PairingIstanbul{}, + common.BytesToAddress([]byte{9}): &blake2F{}, + + common.BytesToAddress([]byte{100}): &tmHeaderValidate{}, + common.BytesToAddress([]byte{101}): &iavlMerkleProofValidatePlanck{}, + common.BytesToAddress([]byte{102}): &blsSignatureVerify{}, + common.BytesToAddress([]byte{103}): &cometBFTLightBlockValidate{}, +} + // PrecompiledContractsBLS contains the set of pre-compiled Ethereum // contracts specified in EIP-2537. These are exported for testing purposes. var PrecompiledContractsBLS = map[common.Address]PrecompiledContract{ @@ -155,6 +175,7 @@ var PrecompiledContractsBLS = map[common.Address]PrecompiledContract{ } var ( + PrecompiledAddressesLuban []common.Address PrecompiledAddressesPlanck []common.Address PrecompiledAddressesMoran []common.Address PrecompiledAddressesNano []common.Address @@ -186,11 +207,16 @@ func init() { 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 params.Rules) []common.Address { switch { + case rules.IsLuban: + return PrecompiledAddressesLuban case rules.IsPlanck: return PrecompiledAddressesPlanck case rules.IsMoran: @@ -271,6 +297,7 @@ type sha256hash struct{} func (c *sha256hash) RequiredGas(input []byte) uint64 { return uint64(len(input)+31)/32*params.Sha256PerWordGas + params.Sha256BaseGas } + func (c *sha256hash) Run(input []byte) ([]byte, error) { h := sha256.Sum256(input) return h[:], nil @@ -286,6 +313,7 @@ type ripemd160hash struct{} func (c *ripemd160hash) RequiredGas(input []byte) uint64 { return uint64(len(input)+31)/32*params.Ripemd160PerWordGas + params.Ripemd160BaseGas } + func (c *ripemd160hash) Run(input []byte) ([]byte, error) { ripemd := ripemd160.New() ripemd.Write(input) @@ -302,6 +330,7 @@ type dataCopy struct{} func (c *dataCopy) RequiredGas(input []byte) uint64 { return uint64(len(input)+31)/32*params.IdentityPerWordGas + params.IdentityBaseGas } + func (c *dataCopy) Run(in []byte) ([]byte, error) { return in, nil } @@ -402,7 +431,7 @@ func (c *bigModExp) RequiredGas(input []byte) uint64 { // def mult_complexity(x): // ceiling(x/8)^2 // - //where is x is max(length_of_MODULUS, length_of_BASE) + // where is x is max(length_of_MODULUS, length_of_BASE) gas = gas.Add(gas, big7) gas = gas.Div(gas, big8) gas.Mul(gas, gas) @@ -1110,3 +1139,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 240a767453..693dffbd39 100644 --- a/core/vm/contracts_lightclient.go +++ b/core/vm/contracts_lightclient.go @@ -10,7 +10,8 @@ import ( "github.com/tendermint/tendermint/crypto/merkle" cmn "github.com/tendermint/tendermint/libs/common" - "github.com/ethereum/go-ethereum/core/vm/lightclient" + v1 "github.com/ethereum/go-ethereum/core/vm/lightclient/v1" + v2 "github.com/ethereum/go-ethereum/core/vm/lightclient/v2" "github.com/ethereum/go-ethereum/params" ) @@ -26,7 +27,7 @@ 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 { @@ -37,11 +38,11 @@ func decodeTendermintHeaderValidationInput(input []byte) (*lightclient.Consensus 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 } @@ -49,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{} func (c *tmHeaderValidate) RequiredGas(input []byte) uint64 { @@ -169,7 +171,7 @@ func (c *iavlMerkleProofValidatePlanck) RequiredGas(_ []byte) uint64 { } func (c *iavlMerkleProofValidatePlanck) Run(input []byte) (result []byte, err error) { - c.basicIavlMerkleProofValidate.proofRuntime = lightclient.Ics23CompatibleProofRuntime() + c.basicIavlMerkleProofValidate.proofRuntime = v1.Ics23CompatibleProofRuntime() c.basicIavlMerkleProofValidate.verifiers = []merkle.ProofOpVerifier{ forbiddenAbsenceOpVerifier, singleValueOpVerifier, @@ -188,7 +190,7 @@ func successfulMerkleResult() []byte { } type basicIavlMerkleProofValidate struct { - keyVerifier lightclient.KeyVerifier + keyVerifier v1.KeyVerifier opsVerifier merkle.ProofOpsVerifier verifiers []merkle.ProofOpVerifier proofRuntime *merkle.ProofRuntime @@ -210,12 +212,12 @@ 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(lightclient.DefaultProofRuntime()) + kvmp.SetProofRuntime(v1.DefaultProofRuntime()) } else { kvmp.SetProofRuntime(c.proofRuntime) } @@ -255,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 { @@ -291,7 +293,7 @@ func proofOpsVerifier(poz merkle.ProofOperators) error { } // for legacy proof type - if _, ok := poz[1].(lightclient.MultiStoreProofOp); ok { + if _, ok := poz[1].(v1.MultiStoreProofOp); ok { if _, ok := poz[0].(iavl.IAVLValueOp); !ok { return cmn.NewError("invalid proof op") } @@ -299,17 +301,17 @@ func proofOpsVerifier(poz merkle.ProofOperators) error { } // for ics23 proof type - if op2, ok := poz[1].(lightclient.CommitmentOp); ok { - if op2.Type != lightclient.ProofOpSimpleMerkleCommitment { + if op2, ok := poz[1].(v1.CommitmentOp); ok { + if op2.Type != v1.ProofOpSimpleMerkleCommitment { return cmn.NewError("invalid proof op") } - op1, ok := poz[0].(lightclient.CommitmentOp) + op1, ok := poz[0].(v1.CommitmentOp) if !ok { return cmn.NewError("invalid proof op") } - if op1.Type != lightclient.ProofOpIAVLCommitment { + if op1.Type != v1.ProofOpIAVLCommitment { return cmn.NewError("invalid proof op") } return nil @@ -327,3 +329,38 @@ func keyVerifier(key string) error { } 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 f0dc814df3..59cec725e9 100644 --- a/core/vm/contracts_lightclient_test.go +++ b/core/vm/contracts_lightclient_test.go @@ -6,13 +6,12 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/tendermint/iavl" "github.com/tendermint/tendermint/crypto/merkle" cmn "github.com/tendermint/tendermint/libs/common" - "github.com/stretchr/testify/require" - - "github.com/ethereum/go-ethereum/core/vm/lightclient" + v1 "github.com/ethereum/go-ethereum/core/vm/lightclient/v1" ) const ( @@ -32,7 +31,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") @@ -53,7 +52,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) @@ -73,7 +72,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 @@ -183,12 +182,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"), }, @@ -203,12 +202,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"), }, @@ -216,8 +215,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"), }, @@ -250,35 +249,35 @@ func TestProofOpsVerifier(t *testing.T) { }, { merkle.ProofOperators{ - lightclient.MultiStoreProofOp{}, - lightclient.MultiStoreProofOp{}, + v1.MultiStoreProofOp{}, + v1.MultiStoreProofOp{}, }, cmn.NewError("invalid proof op"), }, { merkle.ProofOperators{ iavl.IAVLValueOp{}, - lightclient.MultiStoreProofOp{}, + v1.MultiStoreProofOp{}, }, nil, }, { merkle.ProofOperators{ - lightclient.CommitmentOp{Type: lightclient.ProofOpIAVLCommitment}, - lightclient.CommitmentOp{Type: lightclient.ProofOpSimpleMerkleCommitment}, + v1.CommitmentOp{Type: v1.ProofOpIAVLCommitment}, + v1.CommitmentOp{Type: v1.ProofOpSimpleMerkleCommitment}, }, nil, }, { merkle.ProofOperators{ - lightclient.CommitmentOp{Type: lightclient.ProofOpSimpleMerkleCommitment}, - lightclient.CommitmentOp{Type: lightclient.ProofOpSimpleMerkleCommitment}, + v1.CommitmentOp{Type: v1.ProofOpSimpleMerkleCommitment}, + v1.CommitmentOp{Type: v1.ProofOpSimpleMerkleCommitment}, }, cmn.NewError("invalid proof op"), }, { merkle.ProofOperators{ - lightclient.MultiStoreProofOp{}, + v1.MultiStoreProofOp{}, iavl.IAVLValueOp{}, }, cmn.NewError("invalid proof type"), @@ -311,3 +310,16 @@ func TestKeyVerifier(t *testing.T) { 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/contracts_test.go b/core/vm/contracts_test.go index aa8d2f1eb3..80505d7e72 100644 --- a/core/vm/contracts_test.go +++ b/core/vm/contracts_test.go @@ -65,6 +65,7 @@ var allPrecompiles = map[common.Address]PrecompiledContract{ common.BytesToAddress([]byte{16}): &bls12381Pairing{}, common.BytesToAddress([]byte{17}): &bls12381MapG1{}, common.BytesToAddress([]byte{18}): &bls12381MapG2{}, + common.BytesToAddress([]byte{102}): &blsSignatureVerify{}, } // EIP-152 test vectors @@ -179,7 +180,7 @@ func benchmarkPrecompiled(addr string, test precompiledTest, bench *testing.B) { // Keep it as uint64, multiply 100 to get two digit float later mgasps := (100 * 1000 * gasUsed) / elapsed bench.ReportMetric(float64(mgasps)/100, "mgas/s") - //Check if it is correct + // Check if it is correct if err != nil { bench.Error(err) return @@ -231,6 +232,16 @@ func BenchmarkPrecompiledIdentity(bench *testing.B) { benchmarkPrecompiled("04", t, bench) } +// Benchmarks the sample inputs from the blsSignatureVerify precompile. +func BenchmarkPrecompiledBlsSignatureVerify(bench *testing.B) { + t := precompiledTest{ + Input: "f2d8e8e5bf354429e3ce8b97c4e88f7a0bf7bc917e856de762ed6d70dd8ec2d289a04d63285e4b45309e7c180ea82565e375dd62c7b80d957aea4c9b7e16bdb28a0f910036bd3220fe3d7614fb137a8f0a68b3c564ddd214b5041d8f7a124e6e7285ac42635e75eeb9051a052fb500b1c2bc23bd4290db59fc02be11f2b80896b6e22d5b8dd31ba2e49b13cd6be19fcd01c1e23af3e5165d88d8b9deaf38baa77770fa6a358e2eebdffd1bd8a1eb7386", + Expected: "01", + Name: "", + } + benchmarkPrecompiled("66", t, bench) +} + // Tests the sample inputs from the ModExp EIP 198. func TestPrecompiledModExp(t *testing.T) { testJson("modexp", "05", t) } func BenchmarkPrecompiledModExp(b *testing.B) { benchJson("modexp", "05", b) } diff --git a/core/vm/evm.go b/core/vm/evm.go index eb483fd6de..440c47fab0 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -52,6 +52,8 @@ type ( func (evm *EVM) precompile(addr common.Address) (PrecompiledContract, bool) { var precompiles map[common.Address]PrecompiledContract switch { + case evm.chainRules.IsLuban: + precompiles = PrecompiledContractsLuban case evm.chainRules.IsPlanck: precompiles = PrecompiledContractsPlanck case evm.chainRules.IsMoran: @@ -256,7 +258,7 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas gas = 0 } // TODO: consider clearing up unused snapshots: - //} else { + // } else { // evm.StateDB.DiscardSnapshot(snapshot) } return ret, gas, err diff --git a/core/vm/lightclient/ics23_proof.go b/core/vm/lightclient/v1/ics23_proof.go similarity index 99% rename from core/vm/lightclient/ics23_proof.go rename to core/vm/lightclient/v1/ics23_proof.go index 752a82bb68..cd4f340fbe 100644 --- a/core/vm/lightclient/ics23_proof.go +++ b/core/vm/lightclient/v1/ics23_proof.go @@ -1,4 +1,4 @@ -package lightclient +package v1 import ( "fmt" diff --git a/core/vm/lightclient/multistoreproof.go b/core/vm/lightclient/v1/multistoreproof.go similarity index 99% rename from core/vm/lightclient/multistoreproof.go rename to core/vm/lightclient/v1/multistoreproof.go index b7f3618186..d071979655 100644 --- a/core/vm/lightclient/multistoreproof.go +++ b/core/vm/lightclient/v1/multistoreproof.go @@ -1,4 +1,4 @@ -package lightclient +package v1 import ( "bytes" 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 4c26c7d8f9..88c074976d 100644 --- a/core/vm/lightclient/rootmultistore.go +++ b/core/vm/lightclient/v1/rootmultistore.go @@ -1,4 +1,4 @@ -package lightclient +package v1 import ( "fmt" diff --git a/core/vm/lightclient/types.go b/core/vm/lightclient/v1/types.go similarity index 99% rename from core/vm/lightclient/types.go rename to core/vm/lightclient/v1/types.go index 674085b701..1c15db6df6 100644 --- a/core/vm/lightclient/types.go +++ b/core/vm/lightclient/v1/types.go @@ -1,4 +1,4 @@ -package lightclient +package v1 import ( "bytes" 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 381866b146..b8663e06fe 100644 --- a/core/vm/lightclient/utils.go +++ b/core/vm/lightclient/v1/utils.go @@ -1,4 +1,4 @@ -package lightclient +package v1 import ( "fmt" 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 460dfce1de..3570ae9351 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 0000000000..d5de960750 --- /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 0000000000..7519ad2a19 --- /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/core/vote/vote_journal.go b/core/vote/vote_journal.go new file mode 100644 index 0000000000..c11c754e36 --- /dev/null +++ b/core/vote/vote_journal.go @@ -0,0 +1,125 @@ +package vote + +import ( + "encoding/json" + + lru "github.com/hashicorp/golang-lru" + "github.com/tidwall/wal" + + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/metrics" +) + +const ( + maxSizeOfRecentEntry = 512 + maliciousVoteSlashScope = 256 +) + +type VoteJournal struct { + journalPath string // file path of disk journal for saving the vote. + + walLog *wal.Log + + voteDataBuffer *lru.Cache +} + +var voteJournalError = metrics.NewRegisteredGauge("voteJournal/local", nil) + +func NewVoteJournal(filePath string) (*VoteJournal, error) { + walLog, err := wal.Open(filePath, &wal.Options{ + LogFormat: wal.JSON, + SegmentCacheSize: maxSizeOfRecentEntry, + }) + if err != nil { + log.Error("Failed to open vote journal", "err", err) + return nil, err + } + + voteDataBuffer, err := lru.New(maxSizeOfRecentEntry) + if err != nil { + return nil, err + } + + firstIndex, err := walLog.FirstIndex() + if err != nil { + log.Error("Failed to get first index of votes journal", "err", err) + } + + lastIndex, err := walLog.LastIndex() + if err != nil { + log.Error("Failed to get lastIndex of vote journal", "err", err) + return nil, err + } + + voteJournal := &VoteJournal{ + journalPath: filePath, + walLog: walLog, + } + + // Reload all voteData from journal to lru memory everytime node reboot. + for index := firstIndex; index <= lastIndex; index++ { + if voteEnvelop, err := voteJournal.ReadVote(index); err == nil && voteEnvelop != nil { + voteData := voteEnvelop.Data + voteDataBuffer.Add(voteData.TargetNumber, voteData) + } + } + voteJournal.voteDataBuffer = voteDataBuffer + + return voteJournal, nil +} + +func (journal *VoteJournal) WriteVote(voteMessage *types.VoteEnvelope) error { + walLog := journal.walLog + + vote, err := json.Marshal(voteMessage) + if err != nil { + log.Error("Failed to unmarshal vote", "err", err) + return err + } + + lastIndex, err := walLog.LastIndex() + if err != nil { + log.Error("Failed to get lastIndex of vote journal", "err", err) + return err + } + + lastIndex += 1 + if err = walLog.Write(lastIndex, vote); err != nil { + log.Error("Failed to write vote journal", "err", err) + return err + } + + firstIndex, err := walLog.FirstIndex() + if err != nil { + log.Error("Failed to get first index of votes journal", "err", err) + } + + if lastIndex-firstIndex+1 > maxSizeOfRecentEntry { + if err := walLog.TruncateFront(lastIndex - maxSizeOfRecentEntry + 1); err != nil { + log.Error("Failed to truncate votes journal", "err", err) + } + } + + journal.voteDataBuffer.Add(voteMessage.Data.TargetNumber, voteMessage.Data) + return nil +} + +func (journal *VoteJournal) ReadVote(index uint64) (*types.VoteEnvelope, error) { + voteMessage, err := journal.walLog.Read(index) + if err != nil && err != wal.ErrNotFound { + log.Error("Failed to read votes journal", "err", err) + return nil, err + } + + var vote *types.VoteEnvelope + if voteMessage != nil { + vote = &types.VoteEnvelope{} + if err := json.Unmarshal(voteMessage, vote); err != nil { + log.Error("Failed to read vote from voteJournal", "err", err) + return nil, err + } + } + + return vote, nil +} diff --git a/core/vote/vote_manager.go b/core/vote/vote_manager.go new file mode 100644 index 0000000000..fe99418e90 --- /dev/null +++ b/core/vote/vote_manager.go @@ -0,0 +1,224 @@ +package vote + +import ( + "fmt" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/eth/downloader" + "github.com/ethereum/go-ethereum/event" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/metrics" + "github.com/ethereum/go-ethereum/params" +) + +// VoteManager will handle the vote produced by self. +type VoteManager struct { + mux *event.TypeMux + + chain *core.BlockChain + chainconfig *params.ChainConfig + + chainHeadCh chan core.ChainHeadEvent + chainHeadSub event.Subscription + + pool *VotePool + signer *VoteSigner + journal *VoteJournal + + engine consensus.PoSA +} + +func NewVoteManager(mux *event.TypeMux, chainconfig *params.ChainConfig, chain *core.BlockChain, pool *VotePool, journalPath, blsPasswordPath, blsWalletPath string, engine consensus.PoSA) (*VoteManager, error) { + voteManager := &VoteManager{ + mux: mux, + + chain: chain, + chainconfig: chainconfig, + chainHeadCh: make(chan core.ChainHeadEvent, chainHeadChanSize), + + pool: pool, + engine: engine, + } + + // Create voteSigner. + voteSigner, err := NewVoteSigner(blsPasswordPath, blsWalletPath) + if err != nil { + return nil, err + } + log.Info("Create voteSigner successfully") + voteManager.signer = voteSigner + + // Create voteJournal + voteJournal, err := NewVoteJournal(journalPath) + if err != nil { + return nil, err + } + log.Info("Create voteJournal successfully") + voteManager.journal = voteJournal + + // Subscribe to chain head event. + voteManager.chainHeadSub = voteManager.chain.SubscribeChainHeadEvent(voteManager.chainHeadCh) + + go voteManager.loop() + + return voteManager, nil +} + +func (voteManager *VoteManager) loop() { + log.Debug("vote manager routine loop started") + events := voteManager.mux.Subscribe(downloader.StartEvent{}, downloader.DoneEvent{}, downloader.FailedEvent{}) + defer func() { + log.Debug("vote manager loop defer func occur") + if !events.Closed() { + log.Debug("event not closed, unsubscribed by vote manager loop") + events.Unsubscribe() + } + }() + + dlEventCh := events.Chan() + + startVote := true + for { + select { + case ev := <-dlEventCh: + if ev == nil { + log.Debug("dlEvent is nil, continue") + continue + } + switch ev.Data.(type) { + case downloader.StartEvent: + log.Debug("downloader is in startEvent mode, will not startVote") + startVote = false + case downloader.FailedEvent: + log.Debug("downloader is in FailedEvent mode, set startVote flag as true") + startVote = true + case downloader.DoneEvent: + log.Debug("downloader is in DoneEvent mode, set the startVote flag to true") + startVote = true + } + case cHead := <-voteManager.chainHeadCh: + if !startVote { + log.Debug("startVote flag is false, continue") + continue + } + + if cHead.Block == nil { + log.Debug("cHead.Block is nil, continue") + continue + } + + curHead := cHead.Block.Header() + // Check if cur validator is within the validatorSet at curHead + if !voteManager.engine.IsActiveValidatorAt(voteManager.chain, curHead) { + log.Debug("cur validator is not within the validatorSet at curHead") + continue + } + + // Vote for curBlockHeader block. + vote := &types.VoteData{ + TargetNumber: curHead.Number.Uint64(), + TargetHash: curHead.Hash(), + } + voteMessage := &types.VoteEnvelope{ + Data: vote, + } + + // Put Vote into journal and VotesPool if we are active validator and allow to sign it. + if ok, sourceNumber, sourceHash := voteManager.UnderRules(curHead); ok { + log.Debug("curHead is underRules for voting") + if sourceHash == (common.Hash{}) { + log.Debug("sourceHash is empty") + continue + } + + voteMessage.Data.SourceNumber = sourceNumber + voteMessage.Data.SourceHash = sourceHash + + if err := voteManager.signer.SignVote(voteMessage); err != nil { + log.Error("Failed to sign vote", "err", err) + votesSigningErrorMetric(vote.TargetNumber, vote.TargetHash).Inc(1) + continue + } + if err := voteManager.journal.WriteVote(voteMessage); err != nil { + log.Error("Failed to write vote into journal", "err", err) + voteJournalError.Inc(1) + continue + } + + log.Debug("vote manager produced vote", "votedBlockNumber", voteMessage.Data.TargetNumber, "votedBlockHash", voteMessage.Data.TargetHash, "voteMessageHash", voteMessage.Hash()) + voteManager.pool.PutVote(voteMessage) + votesManagerMetric(vote.TargetNumber, vote.TargetHash).Inc(1) + } + case <-voteManager.chainHeadSub.Err(): + log.Debug("voteManager subscribed chainHead failed") + return + } + } +} + +// UnderRules checks if the produced header under the following rules: +// A validator must not publish two distinct votes for the same height. (Rule 1) +// A validator must not vote within the span of its other votes . (Rule 2) +// Validators always vote for their canonical chain’s latest block. (Rule 3) +func (voteManager *VoteManager) UnderRules(header *types.Header) (bool, uint64, common.Hash) { + sourceNumber, sourceHash, err := voteManager.engine.GetJustifiedNumberAndHash(voteManager.chain, header) + if err != nil { + log.Error("failed to get the highest justified number and hash at cur header", "curHeader's BlockNumber", header.Number, "curHeader's BlockHash", header.Hash()) + return false, 0, common.Hash{} + } + + targetNumber := header.Number.Uint64() + + voteDataBuffer := voteManager.journal.voteDataBuffer + //Rule 1: A validator must not publish two distinct votes for the same height. + if voteDataBuffer.Contains(targetNumber) { + log.Debug("err: A validator must not publish two distinct votes for the same height.") + return false, 0, common.Hash{} + } + + //Rule 2: A validator must not vote within the span of its other votes. + blockNumber := sourceNumber + 1 + if blockNumber+maliciousVoteSlashScope < targetNumber { + blockNumber = targetNumber - maliciousVoteSlashScope + } + for ; blockNumber < targetNumber; blockNumber++ { + if voteDataBuffer.Contains(blockNumber) { + voteData, ok := voteDataBuffer.Get(blockNumber) + if !ok { + log.Error("Failed to get voteData info from LRU cache.") + continue + } + if voteData.(*types.VoteData).SourceNumber > sourceNumber { + log.Debug(fmt.Sprintf("error: cur vote %d-->%d is within the span of other votes %d-->%d", + sourceNumber, targetNumber, voteData.(*types.VoteData).SourceNumber, voteData.(*types.VoteData).TargetNumber)) + return false, 0, common.Hash{} + } + } + } + for blockNumber := targetNumber + 1; blockNumber <= targetNumber+upperLimitOfVoteBlockNumber; blockNumber++ { + if voteDataBuffer.Contains(blockNumber) { + voteData, ok := voteDataBuffer.Get(blockNumber) + if !ok { + log.Error("Failed to get voteData info from LRU cache.") + continue + } + if voteData.(*types.VoteData).SourceNumber < sourceNumber { + log.Debug("error: other votes are within span of cur vote") + return false, 0, common.Hash{} + } + } + } + + // Rule 3: Validators always vote for their canonical chain’s latest block. + // Since the header subscribed to is the canonical chain, so this rule is satisified by default. + log.Debug("All three rules check passed") + return true, sourceNumber, sourceHash +} + +// Metrics to monitor if voteManager worked in the expetected logic. +func votesManagerMetric(blockNumber uint64, blockHash common.Hash) metrics.Gauge { + return metrics.GetOrRegisterGauge(fmt.Sprintf("voteManager/blockNumber/%d/blockHash/%s", blockNumber, blockHash), nil) +} diff --git a/core/vote/vote_pool.go b/core/vote/vote_pool.go new file mode 100644 index 0000000000..664f12f76b --- /dev/null +++ b/core/vote/vote_pool.go @@ -0,0 +1,397 @@ +package vote + +import ( + "container/heap" + "sync" + + mapset "github.com/deckarep/golang-set" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/metrics" + "github.com/ethereum/go-ethereum/params" +) + +const ( + maxCurVoteAmountPerBlock = 21 + maxFutureVoteAmountPerBlock = 50 + + voteBufferForPut = 256 + // votes in the range (currentBlockNum-256,currentBlockNum+11] will be stored + lowerLimitOfVoteBlockNumber = 256 + upperLimitOfVoteBlockNumber = 11 // refer to fetcher.maxUncleDist + + chainHeadChanSize = 10 // chainHeadChanSize is the size of channel listening to ChainHeadEvent. +) + +var ( + localCurVotesGauge = metrics.NewRegisteredGauge("curVotes/local", nil) + localFutureVotesGauge = metrics.NewRegisteredGauge("futureVotes/local", nil) + + localReceivedVotesGauge = metrics.NewRegisteredGauge("receivedVotes/local", nil) + + localCurVotesPqGauge = metrics.NewRegisteredGauge("curVotesPq/local", nil) + localFutureVotesPqGauge = metrics.NewRegisteredGauge("futureVotesPq/local", nil) +) + +type VoteBox struct { + blockNumber uint64 + voteMessages []*types.VoteEnvelope +} + +type VotePool struct { + chain *core.BlockChain + chainconfig *params.ChainConfig + mu sync.RWMutex + + votesFeed event.Feed + scope event.SubscriptionScope + + receivedVotes mapset.Set + + curVotes map[common.Hash]*VoteBox + futureVotes map[common.Hash]*VoteBox + + curVotesPq *votesPriorityQueue + futureVotesPq *votesPriorityQueue + + chainHeadCh chan core.ChainHeadEvent + chainHeadSub event.Subscription + + votesCh chan *types.VoteEnvelope + + engine consensus.PoSA +} + +type votesPriorityQueue []*types.VoteData + +func NewVotePool(chainconfig *params.ChainConfig, chain *core.BlockChain, engine consensus.PoSA) *VotePool { + votePool := &VotePool{ + chain: chain, + chainconfig: chainconfig, + receivedVotes: mapset.NewSet(), + curVotes: make(map[common.Hash]*VoteBox), + futureVotes: make(map[common.Hash]*VoteBox), + curVotesPq: &votesPriorityQueue{}, + futureVotesPq: &votesPriorityQueue{}, + chainHeadCh: make(chan core.ChainHeadEvent, chainHeadChanSize), + votesCh: make(chan *types.VoteEnvelope, voteBufferForPut), + engine: engine, + } + + // Subscribe events from blockchain and start the main event loop. + votePool.chainHeadSub = votePool.chain.SubscribeChainHeadEvent(votePool.chainHeadCh) + + go votePool.loop() + return votePool +} + +// loop is the vote pool's main even loop, waiting for and reacting to outside blockchain events and votes channel event. +func (pool *VotePool) loop() { + for { + select { + // Handle ChainHeadEvent. + case ev := <-pool.chainHeadCh: + if ev.Block != nil { + latestBlockNumber := ev.Block.NumberU64() + pool.prune(latestBlockNumber) + pool.transferVotesFromFutureToCur(ev.Block.Header()) + } + case <-pool.chainHeadSub.Err(): + return + + // Handle votes channel and put the vote into vote pool. + case vote := <-pool.votesCh: + pool.putIntoVotePool(vote) + } + } +} + +func (pool *VotePool) PutVote(vote *types.VoteEnvelope) { + pool.votesCh <- vote +} + +func (pool *VotePool) putIntoVotePool(vote *types.VoteEnvelope) bool { + targetNumber := vote.Data.TargetNumber + targetHash := vote.Data.TargetHash + header := pool.chain.CurrentBlock().Header() + headNumber := header.Number.Uint64() + + // Make sure in the range (currentHeight-lowerLimitOfVoteBlockNumber, currentHeight+upperLimitOfVoteBlockNumber]. + if targetNumber+lowerLimitOfVoteBlockNumber-1 < headNumber || targetNumber > headNumber+upperLimitOfVoteBlockNumber { + log.Debug("BlockNumber of vote is outside the range of header-256~header+11, will be discarded") + return false + } + + voteData := &types.VoteData{ + TargetNumber: targetNumber, + TargetHash: targetHash, + } + + var votes map[common.Hash]*VoteBox + var votesPq *votesPriorityQueue + isFutureVote := false + + voteBlock := pool.chain.GetHeaderByHash(targetHash) + if voteBlock == nil { + votes = pool.futureVotes + votesPq = pool.futureVotesPq + isFutureVote = true + } else { + votes = pool.curVotes + votesPq = pool.curVotesPq + } + + voteHash := vote.Hash() + if ok := pool.basicVerify(vote, headNumber, votes, isFutureVote, voteHash); !ok { + return false + } + + if !isFutureVote { + // Verify if the vote comes from valid validators based on voteAddress (BLSPublicKey), only verify curVotes here, will verify futureVotes in transfer process. + if pool.engine.VerifyVote(pool.chain, vote) != nil { + return false + } + + // Send vote for handler usage of broadcasting to peers. + voteEv := core.NewVoteEvent{Vote: vote} + pool.votesFeed.Send(voteEv) + } + + pool.putVote(votes, votesPq, vote, voteData, voteHash, isFutureVote) + + return true +} + +func (pool *VotePool) SubscribeNewVoteEvent(ch chan<- core.NewVoteEvent) event.Subscription { + return pool.scope.Track(pool.votesFeed.Subscribe(ch)) +} + +func (pool *VotePool) putVote(m map[common.Hash]*VoteBox, votesPq *votesPriorityQueue, vote *types.VoteEnvelope, voteData *types.VoteData, voteHash common.Hash, isFutureVote bool) { + targetHash := vote.Data.TargetHash + targetNumber := vote.Data.TargetNumber + + log.Debug("The vote info to put is:", "voteBlockNumber", targetNumber, "voteBlockHash", targetHash) + + pool.mu.Lock() + defer pool.mu.Unlock() + if _, ok := m[targetHash]; !ok { + // Push into votes priorityQueue if not exist in corresponding votes Map. + // To be noted: will not put into priorityQueue if exists in map to avoid duplicate element with the same voteData. + heap.Push(votesPq, voteData) + voteBox := &VoteBox{ + blockNumber: targetNumber, + voteMessages: make([]*types.VoteEnvelope, 0, maxFutureVoteAmountPerBlock), + } + m[targetHash] = voteBox + + if isFutureVote { + localFutureVotesPqGauge.Update(int64(votesPq.Len())) + } else { + localCurVotesPqGauge.Update(int64(votesPq.Len())) + } + } + + // Put into corresponding votes map. + m[targetHash].voteMessages = append(m[targetHash].voteMessages, vote) + // Add into received vote to avoid future duplicated vote comes. + pool.receivedVotes.Add(voteHash) + log.Debug("VoteHash put into votepool is:", "voteHash", voteHash) + + if isFutureVote { + localFutureVotesGauge.Inc(1) + } else { + localCurVotesGauge.Inc(1) + } + localReceivedVotesGauge.Update(int64(pool.receivedVotes.Cardinality())) +} + +func (pool *VotePool) transferVotesFromFutureToCur(latestBlockHeader *types.Header) { + pool.mu.Lock() + defer pool.mu.Unlock() + + futurePq := pool.futureVotesPq + latestBlockNumber := latestBlockHeader.Number.Uint64() + + // For vote in the range [,latestBlockNumber-11), transfer to cur if valid. + for futurePq.Len() > 0 && futurePq.Peek().TargetNumber+upperLimitOfVoteBlockNumber < latestBlockNumber { + blockHash := futurePq.Peek().TargetHash + pool.transfer(blockHash) + } + + // For vote in the range [latestBlockNumber-11,latestBlockNumber], only transfer the vote inside the local fork. + futurePqBuffer := make([]*types.VoteData, 0) + for futurePq.Len() > 0 && futurePq.Peek().TargetNumber <= latestBlockNumber { + blockHash := futurePq.Peek().TargetHash + header := pool.chain.GetHeaderByHash(blockHash) + if header == nil { + // Put into pq buffer used for later put again into futurePq + futurePqBuffer = append(futurePqBuffer, heap.Pop(futurePq).(*types.VoteData)) + continue + } + pool.transfer(blockHash) + } + + for _, voteData := range futurePqBuffer { + heap.Push(futurePq, voteData) + } +} + +func (pool *VotePool) transfer(blockHash common.Hash) { + curPq, futurePq := pool.curVotesPq, pool.futureVotesPq + curVotes, futureVotes := pool.curVotes, pool.futureVotes + voteData := heap.Pop(futurePq) + + defer localFutureVotesPqGauge.Update(int64(futurePq.Len())) + + voteBox, ok := futureVotes[blockHash] + if !ok { + return + } + + validVotes := make([]*types.VoteEnvelope, 0, len(voteBox.voteMessages)) + for _, vote := range voteBox.voteMessages { + // Verify if the vote comes from valid validators based on voteAddress (BLSPublicKey). + if pool.engine.VerifyVote(pool.chain, vote) != nil { + pool.receivedVotes.Remove(vote.Hash()) + continue + } + + // In the process of transfer, send valid vote to votes channel for handler usage + voteEv := core.NewVoteEvent{Vote: vote} + pool.votesFeed.Send(voteEv) + validVotes = append(validVotes, vote) + } + + // may len(curVotes[blockHash].voteMessages) extra maxCurVoteAmountPerBlock, but it doesn't matter + if _, ok := curVotes[blockHash]; !ok { + heap.Push(curPq, voteData) + curVotes[blockHash] = &VoteBox{voteBox.blockNumber, validVotes} + localCurVotesPqGauge.Update(int64(curPq.Len())) + } else { + curVotes[blockHash].voteMessages = append(curVotes[blockHash].voteMessages, validVotes...) + } + + delete(futureVotes, blockHash) + + localCurVotesGauge.Inc(int64(len(validVotes))) + localFutureVotesGauge.Dec(int64(len(voteBox.voteMessages))) +} + +// Prune old data of duplicationSet, curVotePq and curVotesMap. +func (pool *VotePool) prune(latestBlockNumber uint64) { + pool.mu.Lock() + defer pool.mu.Unlock() + curVotes := pool.curVotes + curVotesPq := pool.curVotesPq + + // delete votes in the range [,latestBlockNumber-lowerLimitOfVoteBlockNumber] + for curVotesPq.Len() > 0 && curVotesPq.Peek().TargetNumber+lowerLimitOfVoteBlockNumber-1 < latestBlockNumber { + // Prune curPriorityQueue. + blockHash := heap.Pop(curVotesPq).(*types.VoteData).TargetHash + localCurVotesPqGauge.Update(int64(curVotesPq.Len())) + if voteBox, ok := curVotes[blockHash]; ok { + voteMessages := voteBox.voteMessages + // Prune duplicationSet. + for _, voteMessage := range voteMessages { + voteHash := voteMessage.Hash() + pool.receivedVotes.Remove(voteHash) + } + // Prune curVotes Map. + delete(curVotes, blockHash) + + localCurVotesGauge.Dec(int64(len(voteMessages))) + localReceivedVotesGauge.Update(int64(pool.receivedVotes.Cardinality())) + } + } +} + +// GetVotes as batch. +func (pool *VotePool) GetVotes() []*types.VoteEnvelope { + pool.mu.RLock() + defer pool.mu.RUnlock() + + votesRes := make([]*types.VoteEnvelope, 0) + curVotes := pool.curVotes + for _, voteBox := range curVotes { + votesRes = append(votesRes, voteBox.voteMessages...) + } + return votesRes +} + +func (pool *VotePool) FetchVoteByBlockHash(blockHash common.Hash) []*types.VoteEnvelope { + pool.mu.RLock() + defer pool.mu.RUnlock() + if _, ok := pool.curVotes[blockHash]; ok { + return pool.curVotes[blockHash].voteMessages + } + return nil +} + +func (pool *VotePool) basicVerify(vote *types.VoteEnvelope, headNumber uint64, m map[common.Hash]*VoteBox, isFutureVote bool, voteHash common.Hash) bool { + targetHash := vote.Data.TargetHash + pool.mu.RLock() + defer pool.mu.RUnlock() + + // Check duplicate voteMessage firstly. + if pool.receivedVotes.Contains(voteHash) { + log.Debug("Vote pool already contained the same vote", "voteHash", voteHash) + return false + } + + // To prevent DOS attacks, make sure no more than 21 votes per blockHash if not futureVotes + // and no more than 50 votes per blockHash if futureVotes. + maxVoteAmountPerBlock := maxCurVoteAmountPerBlock + if isFutureVote { + maxVoteAmountPerBlock = maxFutureVoteAmountPerBlock + } + if voteBox, ok := m[targetHash]; ok { + if len(voteBox.voteMessages) >= maxVoteAmountPerBlock { + return false + } + } + + // Verify bls signature. + if err := vote.Verify(); err != nil { + log.Error("Failed to verify voteMessage", "err", err) + return false + } + + return true +} + +func (pq votesPriorityQueue) Less(i, j int) bool { + return pq[i].TargetNumber < pq[j].TargetNumber +} + +func (pq votesPriorityQueue) Len() int { + return len(pq) +} + +func (pq votesPriorityQueue) Swap(i, j int) { + pq[i], pq[j] = pq[j], pq[i] +} + +func (pq *votesPriorityQueue) Push(vote interface{}) { + curVote := vote.(*types.VoteData) + *pq = append(*pq, curVote) +} + +func (pq *votesPriorityQueue) Pop() interface{} { + tmp := *pq + l := len(tmp) + var res interface{} = tmp[l-1] + *pq = tmp[:l-1] + return res +} + +func (pq *votesPriorityQueue) Peek() *types.VoteData { + if pq.Len() == 0 { + return nil + } + return (*pq)[0] +} diff --git a/core/vote/vote_pool_test.go b/core/vote/vote_pool_test.go new file mode 100644 index 0000000000..a1bcd8d232 --- /dev/null +++ b/core/vote/vote_pool_test.go @@ -0,0 +1,446 @@ +// 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 vote + +import ( + "container/heap" + "context" + "encoding/json" + "fmt" + "io/ioutil" + "math/big" + "os" + "path/filepath" + "testing" + "time" + + "github.com/google/uuid" + "github.com/prysmaticlabs/prysm/v3/crypto/bls" + "github.com/prysmaticlabs/prysm/v3/validator/accounts" + "github.com/prysmaticlabs/prysm/v3/validator/accounts/iface" + "github.com/prysmaticlabs/prysm/v3/validator/keymanager" + keystorev4 "github.com/wealdtech/go-eth2-wallet-encryptor-keystorev4" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus" + "github.com/ethereum/go-ethereum/consensus/ethash" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/eth/downloader" + "github.com/ethereum/go-ethereum/event" + "github.com/ethereum/go-ethereum/params" +) + +var ( + // testKey is a private key to use for funding a tester account. + testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") + + // testAddr is the Ethereum address of the tester account. + testAddr = crypto.PubkeyToAddress(testKey.PublicKey) + + password = "secretPassword" + + timeThreshold = 30 +) + +type mockPOSA struct { + consensus.PoSA +} + +type mockInvalidPOSA struct { + consensus.PoSA +} + +func (p *mockPOSA) GetJustifiedNumberAndHash(chain consensus.ChainHeaderReader, header *types.Header) (uint64, common.Hash, error) { + parentHeader := chain.GetHeaderByHash(header.ParentHash) + if parentHeader == nil { + return 0, common.Hash{}, fmt.Errorf("unexpected error") + } + return parentHeader.Number.Uint64(), parentHeader.Hash(), nil +} + +func (p *mockInvalidPOSA) GetJustifiedNumberAndHash(chain consensus.ChainHeaderReader, header *types.Header) (uint64, common.Hash, error) { + return 0, common.Hash{}, fmt.Errorf("not supported") +} + +func (m *mockPOSA) VerifyVote(chain consensus.ChainHeaderReader, vote *types.VoteEnvelope) error { + return nil +} + +func (m *mockInvalidPOSA) VerifyVote(chain consensus.ChainHeaderReader, vote *types.VoteEnvelope) error { + return nil +} + +func (m *mockPOSA) IsActiveValidatorAt(chain consensus.ChainHeaderReader, header *types.Header) bool { + return true +} + +func (m *mockInvalidPOSA) IsActiveValidatorAt(chain consensus.ChainHeaderReader, header *types.Header) bool { + return true +} + +func (pool *VotePool) verifyStructureSizeOfVotePool(receivedVotes, curVotes, futureVotes, curVotesPq, futureVotesPq int) bool { + for i := 0; i < timeThreshold; i++ { + time.Sleep(1 * time.Second) + if pool.receivedVotes.Cardinality() == receivedVotes && len(pool.curVotes) == curVotes && len(pool.futureVotes) == futureVotes && pool.curVotesPq.Len() == curVotesPq && pool.futureVotesPq.Len() == futureVotesPq { + return true + } + } + return false +} + +func (journal *VoteJournal) verifyJournal(size, lastLatestVoteNumber int) bool { + for i := 0; i < timeThreshold; i++ { + time.Sleep(1 * time.Second) + lastIndex, _ := journal.walLog.LastIndex() + firstIndex, _ := journal.walLog.FirstIndex() + if int(lastIndex)-int(firstIndex)+1 == size { + return true + } + lastVote, _ := journal.ReadVote(lastIndex) + if lastVote != nil && lastVote.Data.TargetNumber == uint64(lastLatestVoteNumber) { + return true + } + } + return false +} + +func TestValidVotePool(t *testing.T) { + testVotePool(t, true) +} + +func TestInvalidVotePool(t *testing.T) { + testVotePool(t, false) +} + +func testVotePool(t *testing.T, isValidRules bool) { + walletPasswordDir, walletDir := setUpKeyManager(t) + + // Create a database pre-initialize with a genesis block + db := rawdb.NewMemoryDatabase() + (&core.Genesis{ + Config: params.TestChainConfig, + Alloc: core.GenesisAlloc{testAddr: {Balance: big.NewInt(1000000)}}, + }).MustCommit(db) + + chain, _ := core.NewBlockChain(db, nil, params.TestChainConfig, ethash.NewFullFaker(), vm.Config{}, nil, nil) + + mux := new(event.TypeMux) + + var mockEngine consensus.PoSA + if isValidRules { + mockEngine = &mockPOSA{} + } else { + mockEngine = &mockInvalidPOSA{} + } + + // Create vote pool + votePool := NewVotePool(params.TestChainConfig, chain, mockEngine) + + // Create vote manager + // Create a temporary file for the votes journal + file, err := ioutil.TempFile("", "") + if err != nil { + t.Fatalf("failed to create temporary file path: %v", err) + } + journal := file.Name() + defer os.Remove(journal) + + // Clean up the temporary file, we only need the path for now + file.Close() + os.Remove(journal) + + voteManager, err := NewVoteManager(mux, params.TestChainConfig, chain, votePool, journal, walletPasswordDir, walletDir, mockEngine) + if err != nil { + t.Fatalf("failed to create vote managers") + } + + voteJournal := voteManager.journal + + // Send the done event of downloader + time.Sleep(10 * time.Millisecond) + mux.Post(downloader.DoneEvent{}) + + bs, _ := core.GenerateChain(params.TestChainConfig, chain.Genesis(), ethash.NewFaker(), db, 1, nil) + if _, err := chain.InsertChain(bs); err != nil { + panic(err) + } + for i := 0; i < 10; i++ { + bs, _ = core.GenerateChain(params.TestChainConfig, bs[len(bs)-1], ethash.NewFaker(), db, 1, nil) + if _, err := chain.InsertChain(bs); err != nil { + panic(err) + } + } + + if !isValidRules { + if votePool.verifyStructureSizeOfVotePool(11, 11, 0, 11, 0) { + t.Fatalf("put vote failed") + } + return + } + + if !votePool.verifyStructureSizeOfVotePool(11, 11, 0, 11, 0) { + t.Fatalf("put vote failed") + } + + // Verify if votesPq is min heap + votesPq := votePool.curVotesPq + pqBuffer := make([]*types.VoteData, 0) + lastVotedBlockNumber := uint64(0) + for votesPq.Len() > 0 { + voteData := heap.Pop(votesPq).(*types.VoteData) + if voteData.TargetNumber < lastVotedBlockNumber { + t.Fatalf("votesPq verification failed") + } + lastVotedBlockNumber = voteData.TargetNumber + pqBuffer = append(pqBuffer, voteData) + } + for _, voteData := range pqBuffer { + heap.Push(votesPq, voteData) + } + + // Verify journal + if !voteJournal.verifyJournal(11, 11) { + t.Fatalf("journal failed") + } + + bs, _ = core.GenerateChain(params.TestChainConfig, bs[len(bs)-1], ethash.NewFaker(), db, 1, nil) + if _, err := chain.InsertChain(bs); err != nil { + panic(err) + } + + if !votePool.verifyStructureSizeOfVotePool(12, 12, 0, 12, 0) { + t.Fatalf("put vote failed") + } + + // Verify journal + if !voteJournal.verifyJournal(12, 12) { + t.Fatalf("journal failed") + } + + for i := 0; i < 256; i++ { + bs, _ = core.GenerateChain(params.TestChainConfig, bs[len(bs)-1], ethash.NewFaker(), db, 1, nil) + if _, err := chain.InsertChain(bs); err != nil { + panic(err) + } + } + + // Verify journal + if !voteJournal.verifyJournal(268, 268) { + t.Fatalf("journal failed") + } + + // currently chain size is 268, and votePool should be pruned, so vote pool size should be 256! + if !votePool.verifyStructureSizeOfVotePool(256, 256, 0, 256, 0) { + t.Fatalf("put vote failed") + } + + // Test invalid vote whose number larger than latestHeader + 13 + invalidVote := &types.VoteEnvelope{ + Data: &types.VoteData{ + TargetNumber: 1000, + }, + } + voteManager.pool.PutVote(invalidVote) + + if !votePool.verifyStructureSizeOfVotePool(256, 256, 0, 256, 0) { + t.Fatalf("put vote failed") + } + + votes := votePool.GetVotes() + if len(votes) != 256 { + t.Fatalf("get votes failed") + } + + // Verify journal + if !voteJournal.verifyJournal(268, 268) { + t.Fatalf("journal failed") + } + + // Test future votes scenario: votes number within latestBlockHeader ~ latestBlockHeader + 13 + futureVote := &types.VoteEnvelope{ + Data: &types.VoteData{ + TargetNumber: 279, + }, + } + if err := voteManager.signer.SignVote(futureVote); err != nil { + t.Fatalf("sign vote failed") + } + voteManager.pool.PutVote(futureVote) + + if !votePool.verifyStructureSizeOfVotePool(257, 256, 1, 256, 1) { + t.Fatalf("put vote failed") + } + + // Verify journal + if !voteJournal.verifyJournal(268, 268) { + t.Fatalf("journal failed") + } + + // Test duplicate vote case, shouldn'd be put into vote pool + duplicateVote := &types.VoteEnvelope{ + Data: &types.VoteData{ + TargetNumber: 279, + }, + } + if err := voteManager.signer.SignVote(duplicateVote); err != nil { + t.Fatalf("sign vote failed") + } + voteManager.pool.PutVote(duplicateVote) + + if !votePool.verifyStructureSizeOfVotePool(257, 256, 1, 256, 1) { + t.Fatalf("put vote failed") + } + + // Verify journal + if !voteJournal.verifyJournal(268, 268) { + t.Fatalf("journal failed") + } + + // Test future votes larger than latestBlockNumber + 13 should be rejected + futureVote = &types.VoteEnvelope{ + Data: &types.VoteData{ + TargetNumber: 282, + TargetHash: common.Hash{}, + }, + } + voteManager.pool.PutVote(futureVote) + if !votePool.verifyStructureSizeOfVotePool(257, 256, 1, 256, 1) { + t.Fatalf("put vote failed") + } + + // Test transfer votes from future to cur, latest block header is #288 after the following generation + // For the above BlockNumber 279, it did not have blockHash, should be assigned as well below. + curNumber := 268 + var futureBlockHash common.Hash + for i := 0; i < 20; i++ { + bs, _ = core.GenerateChain(params.TestChainConfig, bs[len(bs)-1], ethash.NewFaker(), db, 1, nil) + curNumber += 1 + if curNumber == 279 { + futureBlockHash = bs[0].Hash() + futureVotesMap := votePool.futureVotes + voteBox := futureVotesMap[common.Hash{}] + futureVotesMap[futureBlockHash] = voteBox + delete(futureVotesMap, common.Hash{}) + futureVotesPq := votePool.futureVotesPq + futureVotesPq.Peek().TargetHash = futureBlockHash + } + if _, err := chain.InsertChain(bs); err != nil { + panic(err) + } + } + + for i := 0; i < timeThreshold; i++ { + time.Sleep(1 * time.Second) + _, ok := votePool.curVotes[futureBlockHash] + if ok && len(votePool.curVotes[futureBlockHash].voteMessages) == 2 { + break + } + } + if votePool.curVotes[futureBlockHash] == nil || len(votePool.curVotes[futureBlockHash].voteMessages) != 2 { + t.Fatalf("transfer vote failed") + } + + // Pruner will keep the size of votePool as latestBlockHeader-255~latestBlockHeader, then final result should be 256! + if !votePool.verifyStructureSizeOfVotePool(257, 256, 0, 256, 0) { + t.Fatalf("put vote failed") + } + + // Verify journal + if !voteJournal.verifyJournal(288, 288) { + t.Fatalf("journal failed") + } + + for i := 0; i < 224; i++ { + bs, _ = core.GenerateChain(params.TestChainConfig, bs[len(bs)-1], ethash.NewFaker(), db, 1, nil) + if _, err := chain.InsertChain(bs); err != nil { + panic(err) + } + } + + // Verify journal + if !voteJournal.verifyJournal(512, 512) { + t.Fatalf("journal failed") + } + + bs, _ = core.GenerateChain(params.TestChainConfig, bs[len(bs)-1], ethash.NewFaker(), db, 1, nil) + if _, err := chain.InsertChain(bs); err != nil { + panic(err) + } + + // Verify if journal no longer than 512 + if !voteJournal.verifyJournal(512, 513) { + t.Fatalf("journal failed") + } +} + +func setUpKeyManager(t *testing.T) (string, string) { + walletDir := filepath.Join(t.TempDir(), "wallet") + opts := []accounts.Option{} + opts = append(opts, accounts.WithWalletDir(walletDir)) + opts = append(opts, accounts.WithWalletPassword(password)) + opts = append(opts, accounts.WithKeymanagerType(keymanager.Local)) + opts = append(opts, accounts.WithSkipMnemonicConfirm(true)) + acc, err := accounts.NewCLIManager(opts...) + if err != nil { + t.Fatalf("New Accounts CLI Manager failed: %v.", err) + } + walletPasswordDir := filepath.Join(t.TempDir(), "password") + if err := os.MkdirAll(filepath.Dir(walletPasswordDir), 0700); err != nil { + t.Fatalf("failed to create walletPassword dir: %v", err) + } + if err := ioutil.WriteFile(walletPasswordDir, []byte(password), 0600); err != nil { + t.Fatalf("failed to write wallet password dir: %v", err) + } + + w, err := acc.WalletCreate(context.Background()) + if err != nil { + t.Fatalf("failed to create wallet: %v", err) + } + km, _ := w.InitializeKeymanager(context.Background(), iface.InitKeymanagerConfig{ListenForChanges: false}) + k, _ := km.(keymanager.Importer) + secretKey, _ := bls.RandKey() + encryptor := keystorev4.New() + pubKeyBytes := secretKey.PublicKey().Marshal() + cryptoFields, err := encryptor.Encrypt(secretKey.Marshal(), password) + if err != nil { + t.Fatalf("failed: %v", err) + } + + id, _ := uuid.NewRandom() + keystore := &keymanager.Keystore{ + Crypto: cryptoFields, + ID: id.String(), + Pubkey: fmt.Sprintf("%x", pubKeyBytes), + Version: encryptor.Version(), + Name: encryptor.Name(), + } + + encodedFile, _ := json.MarshalIndent(keystore, "", "\t") + keyStoreDir := filepath.Join(t.TempDir(), "keystore") + keystoreFile, _ := os.Create(fmt.Sprintf("%s/keystore-%s.json", keyStoreDir, "publichh")) + keystoreFile.Write(encodedFile) + accounts.ImportAccounts(context.Background(), &accounts.ImportAccountsConfig{ + Importer: k, + Keystores: []*keymanager.Keystore{keystore}, + AccountPassword: password, + }) + return walletPasswordDir, walletDir +} diff --git a/core/vote/vote_signer.go b/core/vote/vote_signer.go new file mode 100644 index 0000000000..1ea7c95f14 --- /dev/null +++ b/core/vote/vote_signer.go @@ -0,0 +1,110 @@ +package vote + +import ( + "context" + "fmt" + "io/ioutil" + "time" + + "github.com/pkg/errors" + + "github.com/prysmaticlabs/prysm/v3/crypto/bls" + validatorpb "github.com/prysmaticlabs/prysm/v3/proto/prysm/v1alpha1/validator-client" + "github.com/prysmaticlabs/prysm/v3/validator/accounts/iface" + "github.com/prysmaticlabs/prysm/v3/validator/accounts/wallet" + "github.com/prysmaticlabs/prysm/v3/validator/keymanager" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/metrics" +) + +const ( + voteSignerTimeout = time.Second * 5 +) + +type VoteSigner struct { + km *keymanager.IKeymanager + pubKey [48]byte +} + +func NewVoteSigner(blsPasswordPath, blsWalletPath string) (*VoteSigner, error) { + dirExists, err := wallet.Exists(blsWalletPath) + if err != nil { + log.Error("Check BLS wallet exists", "err", err) + return nil, err + } + if !dirExists { + log.Error("BLS wallet did not exists.") + return nil, fmt.Errorf("BLS wallet did not exists.") + } + + walletPassword, err := ioutil.ReadFile(blsPasswordPath) + if err != nil { + log.Error("Read BLS wallet password", "err", err) + return nil, err + } + log.Info("Read BLS wallet password successfully") + + w, err := wallet.OpenWallet(context.Background(), &wallet.Config{ + WalletDir: blsWalletPath, + WalletPassword: string(walletPassword), + }) + if err != nil { + log.Error("Open BLS wallet failed", "err", err) + return nil, err + } + log.Info("Open BLS wallet successfully") + + km, err := w.InitializeKeymanager(context.Background(), iface.InitKeymanagerConfig{ListenForChanges: false}) + if err != nil { + log.Error("Initialize key manager failed", "err", err) + return nil, err + } + log.Info("Initialized keymanager successfully") + + ctx, cancel := context.WithTimeout(context.Background(), voteSignerTimeout) + defer cancel() + + pubKeys, err := km.FetchValidatingPublicKeys(ctx) + if err != nil { + return nil, errors.Wrap(err, "could not fetch validating public keys") + } + + return &VoteSigner{ + km: &km, + pubKey: pubKeys[0], + }, nil +} + +func (signer *VoteSigner) SignVote(vote *types.VoteEnvelope) error { + // Sign the vote, fetch the first pubKey as validator's bls public key. + pubKey := signer.pubKey + blsPubKey, err := bls.PublicKeyFromBytes(pubKey[:]) + if err != nil { + return errors.Wrap(err, "convert public key from bytes to bls failed") + } + + voteDataHash := vote.Data.Hash() + + ctx, cancel := context.WithTimeout(context.Background(), voteSignerTimeout) + defer cancel() + + signature, err := (*signer.km).Sign(ctx, &validatorpb.SignRequest{ + PublicKey: pubKey[:], + SigningRoot: voteDataHash[:], + }) + if err != nil { + return err + } + + copy(vote.VoteAddress[:], blsPubKey.Marshal()[:]) + copy(vote.Signature[:], signature.Marshal()[:]) + return nil +} + +// Metrics to indicate if there's any failed signing. +func votesSigningErrorMetric(blockNumber uint64, blockHash common.Hash) metrics.Gauge { + return metrics.GetOrRegisterGauge(fmt.Sprintf("voteSigning/blockNumber/%d/blockHash/%s", blockNumber, blockHash), nil) +} diff --git a/docker/Dockerfile b/docker/Dockerfile index b703371707..484a12f45b 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,9 +1,11 @@ FROM golang:1.19-alpine as bsc -RUN apk add --no-cache make gcc musl-dev linux-headers git bash +RUN apk add --no-cache make cmake gcc musl-dev linux-headers git bash build-base libc-dev ADD . /bsc WORKDIR /bsc +ENV CGO_CFLAGS="-O -D__BLST_PORTABLE__" +ENV CGO_CFLAGS_ALLOW="-O -D__BLST_PORTABLE__" RUN make geth RUN mv /bsc/build/bin/geth /usr/local/bin/geth @@ -12,7 +14,7 @@ ENTRYPOINT [ "/usr/local/bin/geth" ] FROM ethereum/solc:0.6.4-alpine as bsc-genesis -RUN apk add --d --no-cache ca-certificates npm nodejs bash alpine-sdk +RUN apk add --no-cache ca-certificates npm nodejs bash alpine-sdk expect RUN git clone https://github.com/binance-chain/bsc-genesis-contract.git /root/genesis \ && cd /root/genesis && npm install diff --git a/docker/Dockerfile.truffle b/docker/Dockerfile.truffle index 28ab9da393..93675241c2 100644 --- a/docker/Dockerfile.truffle +++ b/docker/Dockerfile.truffle @@ -1,6 +1,6 @@ FROM ethereum/solc:0.6.4-alpine -RUN apk add --d --no-cache ca-certificates npm nodejs bash alpine-sdk git +RUN apk add --no-cache ca-certificates npm nodejs bash alpine-sdk git RUN git clone https://github.com/binance-chain/canonical-upgradeable-bep20.git /usr/app/canonical-upgradeable-bep20 diff --git a/eth/api.go b/eth/api.go index f81dfa922b..f7e16b9d61 100644 --- a/eth/api.go +++ b/eth/api.go @@ -282,16 +282,24 @@ func (api *PublicDebugAPI) DumpBlock(blockNr rpc.BlockNumber) (state.Dump, error _, stateDb := api.eth.miner.Pending() return stateDb.RawDump(opts), nil } - var block *types.Block + var header *types.Header if blockNr == rpc.LatestBlockNumber { - block = api.eth.blockchain.CurrentBlock() + header = api.eth.blockchain.CurrentHeader() + } else if blockNr == rpc.FinalizedBlockNumber { + header = api.eth.blockchain.CurrentFinalBlock() + } else if blockNr == rpc.SafeBlockNumber { + header = api.eth.blockchain.CurrentSafeBlock() } else { - block = api.eth.blockchain.GetBlockByNumber(uint64(blockNr)) + block := api.eth.blockchain.GetBlockByNumber(uint64(blockNr)) + if block == nil { + return state.Dump{}, fmt.Errorf("block #%d not found", blockNr) + } + header = block.Header() } - if block == nil { + if header == nil { return state.Dump{}, fmt.Errorf("block #%d not found", blockNr) } - stateDb, err := api.eth.BlockChain().StateAt(block.Root()) + stateDb, err := api.eth.BlockChain().StateAt(header.Root) if err != nil { return state.Dump{}, err } @@ -370,16 +378,24 @@ func (api *PublicDebugAPI) AccountRange(blockNrOrHash rpc.BlockNumberOrHash, sta // the miner and operate on those _, stateDb = api.eth.miner.Pending() } else { - var block *types.Block + var header *types.Header if number == rpc.LatestBlockNumber { - block = api.eth.blockchain.CurrentBlock() + header = api.eth.blockchain.CurrentHeader() + } else if number == rpc.FinalizedBlockNumber { + header = api.eth.blockchain.CurrentFinalBlock() + } else if number == rpc.SafeBlockNumber { + header = api.eth.blockchain.CurrentSafeBlock() } else { - block = api.eth.blockchain.GetBlockByNumber(uint64(number)) + block := api.eth.blockchain.GetBlockByNumber(uint64(number)) + if block == nil { + return state.IteratorDump{}, fmt.Errorf("block #%d not found", number) + } + header = block.Header() } - if block == nil { + if header == nil { return state.IteratorDump{}, fmt.Errorf("block #%d not found", number) } - stateDb, err = api.eth.BlockChain().StateAt(block.Root()) + stateDb, err = api.eth.BlockChain().StateAt(header.Root) if err != nil { return state.IteratorDump{}, err } diff --git a/eth/api_backend.go b/eth/api_backend.go index 7c0f1f0482..dc48c3f073 100644 --- a/eth/api_backend.go +++ b/eth/api_backend.go @@ -19,6 +19,7 @@ package eth import ( "context" "errors" + "fmt" "math/big" "time" @@ -32,6 +33,7 @@ import ( "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/eth/downloader" "github.com/ethereum/go-ethereum/eth/gasprice" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/event" @@ -70,7 +72,21 @@ func (b *EthAPIBackend) HeaderByNumber(ctx context.Context, number rpc.BlockNumb } // Otherwise resolve and return the block if number == rpc.LatestBlockNumber { - return b.eth.blockchain.CurrentBlock().Header(), nil + return b.eth.blockchain.CurrentHeader(), nil + } + if number == rpc.FinalizedBlockNumber { + block := b.eth.blockchain.CurrentFinalBlock() + if block != nil { + return block, nil + } + return nil, errors.New("finalized block not found") + } + if number == rpc.SafeBlockNumber { + block := b.eth.blockchain.CurrentSafeBlock() + if block != nil { + return block, nil + } + return nil, errors.New("safe block not found") } return b.eth.blockchain.GetHeaderByNumber(uint64(number)), nil } @@ -106,6 +122,20 @@ func (b *EthAPIBackend) BlockByNumber(ctx context.Context, number rpc.BlockNumbe if number == rpc.LatestBlockNumber { return b.eth.blockchain.CurrentBlock(), nil } + if number == rpc.FinalizedBlockNumber { + header := b.eth.blockchain.CurrentFinalBlock() + if header == nil { + return nil, fmt.Errorf("block #%d not found", number) + } + return b.eth.blockchain.GetBlock(header.Hash(), header.Number.Uint64()), nil + } + if number == rpc.SafeBlockNumber { + header := b.eth.blockchain.CurrentSafeBlock() + if header == nil { + return nil, fmt.Errorf("block #%d not found", number) + } + return b.eth.blockchain.GetBlock(header.Hash(), header.Number.Uint64()), nil + } return b.eth.blockchain.GetBlockByNumber(uint64(number)), nil } @@ -227,6 +257,10 @@ func (b *EthAPIBackend) SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) e return b.eth.BlockChain().SubscribeChainHeadEvent(ch) } +func (b *EthAPIBackend) SubscribeFinalizedHeaderEvent(ch chan<- core.FinalizedHeaderEvent) event.Subscription { + return b.eth.BlockChain().SubscribeFinalizedHeaderEvent(ch) +} + func (b *EthAPIBackend) SubscribeChainSideEvent(ch chan<- core.ChainSideEvent) event.Subscription { return b.eth.BlockChain().SubscribeChainSideEvent(ch) } @@ -281,6 +315,17 @@ func (b *EthAPIBackend) SubscribeNewTxsEvent(ch chan<- core.NewTxsEvent) event.S return b.eth.TxPool().SubscribeNewTxsEvent(ch) } +func (b *EthAPIBackend) SubscribeNewVoteEvent(ch chan<- core.NewVoteEvent) event.Subscription { + if b.eth.VotePool() == nil { + return nil + } + return b.eth.VotePool().SubscribeNewVoteEvent(ch) +} + +func (b *EthAPIBackend) Downloader() *downloader.Downloader { + return b.eth.Downloader() +} + func (b *EthAPIBackend) SyncProgress() ethereum.SyncProgress { return b.eth.Downloader().Progress() } diff --git a/eth/backend.go b/eth/backend.go index fc0ca6534c..3dccb96f3f 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -39,11 +39,12 @@ import ( "github.com/ethereum/go-ethereum/core/state/pruner" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/core/vote" "github.com/ethereum/go-ethereum/eth/downloader" "github.com/ethereum/go-ethereum/eth/ethconfig" "github.com/ethereum/go-ethereum/eth/filters" "github.com/ethereum/go-ethereum/eth/gasprice" - "github.com/ethereum/go-ethereum/eth/protocols/diff" + "github.com/ethereum/go-ethereum/eth/protocols/bsc" "github.com/ethereum/go-ethereum/eth/protocols/eth" "github.com/ethereum/go-ethereum/eth/protocols/snap" "github.com/ethereum/go-ethereum/eth/protocols/trust" @@ -77,6 +78,7 @@ type Ethereum struct { ethDialCandidates enode.Iterator snapDialCandidates enode.Iterator trustDialCandidates enode.Iterator + bscDialCandidates enode.Iterator merger *consensus.Merger // DB interfaces @@ -104,6 +106,8 @@ type Ethereum struct { lock sync.RWMutex // Protects the variadic fields (e.g. gas price and etherbase) shutdownTracker *shutdowncheck.ShutdownTracker // Tracks if and when the node has shutdown ungracefully + + votePool *vote.VotePool } // New creates a new Ethereum object (including the @@ -244,6 +248,31 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { } eth.txPool = core.NewTxPool(config.TxPool, chainConfig, eth.blockchain) + // Create voteManager instance + if posa, ok := eth.engine.(consensus.PoSA); ok { + // Create votePool instance + votePool := vote.NewVotePool(chainConfig, eth.blockchain, posa) + eth.votePool = votePool + if parlia, ok := eth.engine.(*parlia.Parlia); ok { + parlia.VotePool = votePool + } else { + return nil, fmt.Errorf("Engine is not Parlia type") + } + log.Info("Create votePool successfully") + + if config.Miner.VoteEnable { + conf := stack.Config() + blsPasswordPath := stack.ResolvePath(conf.BLSPasswordFile) + blsWalletPath := stack.ResolvePath(conf.BLSWalletDir) + voteJournalPath := stack.ResolvePath(conf.VoteJournalDir) + if _, err := vote.NewVoteManager(eth.EventMux(), chainConfig, eth.blockchain, votePool, voteJournalPath, blsPasswordPath, blsWalletPath, posa); err != nil { + log.Error("Failed to Initialize voteManager", "err", err) + return nil, err + } + log.Info("Create voteManager successfully") + } + } + // Permit the downloader to use the trie cache allowance during fast sync cacheLimit := cacheConfig.TrieCleanLimit + cacheConfig.TrieDirtyLimit + cacheConfig.SnapshotLimit checkpoint := config.Checkpoint @@ -269,6 +298,9 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { }); err != nil { return nil, err } + if eth.votePool != nil { + eth.handler.votepool = eth.votePool + } eth.miner = miner.New(eth, &config.Miner, chainConfig, eth.EventMux(), eth.engine, eth.isLocalBlock) eth.miner.SetExtra(makeExtraData(config.Miner.ExtraData)) @@ -293,6 +325,10 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { if err != nil { return nil, err } + eth.bscDialCandidates, err = dnsclient.NewIterator(eth.config.BscDiscoveryURLs...) + if err != nil { + return nil, err + } // Start the RPC service eth.netRPCService = ethapi.NewPublicNetAPI(eth.p2pServer, config.NetworkId) @@ -558,6 +594,7 @@ func (s *Ethereum) Miner() *miner.Miner { return s.miner } func (s *Ethereum) AccountManager() *accounts.Manager { return s.accountManager } func (s *Ethereum) BlockChain() *core.BlockChain { return s.blockchain } func (s *Ethereum) TxPool() *core.TxPool { return s.txPool } +func (s *Ethereum) VotePool() *vote.VotePool { return s.votePool } func (s *Ethereum) EventMux() *event.TypeMux { return s.eventMux } func (s *Ethereum) Engine() consensus.Engine { return s.engine } func (s *Ethereum) ChainDb() ethdb.Database { return s.chainDb } @@ -581,12 +618,15 @@ func (s *Ethereum) Protocols() []p2p.Protocol { protos = append(protos, snap.MakeProtocols((*snapHandler)(s.handler), s.snapDialCandidates)...) } // diff protocol can still open without snap protocol - if !s.config.DisableDiffProtocol { - protos = append(protos, diff.MakeProtocols((*diffHandler)(s.handler), s.snapDialCandidates)...) - } + // if !s.config.DisableDiffProtocol { + // protos = append(protos, diff.MakeProtocols((*diffHandler)(s.handler), s.snapDialCandidates)...) + // } if s.config.EnableTrustProtocol { protos = append(protos, trust.MakeProtocols((*trustHandler)(s.handler), s.snapDialCandidates)...) } + if !s.config.DisableBscProtocol { + protos = append(protos, bsc.MakeProtocols((*bscHandler)(s.handler), s.bscDialCandidates)...) + } return protos } @@ -621,6 +661,7 @@ func (s *Ethereum) Stop() error { s.ethDialCandidates.Close() s.snapDialCandidates.Close() s.trustDialCandidates.Close() + s.bscDialCandidates.Close() s.handler.Stop() // Then stop everything else. diff --git a/eth/downloader/downloader.go b/eth/downloader/downloader.go index a5ac153afc..70dc7e15b9 100644 --- a/eth/downloader/downloader.go +++ b/eth/downloader/downloader.go @@ -374,8 +374,8 @@ func (d *Downloader) UnregisterPeer(id string) error { return nil } -// Synchronise tries to sync up our local block chain with a remote peer, both -// adding various sanity checks as well as wrapping it with various log entries. +// Synchronise tries to sync up our local blockchain with a remote peer, both +// adding various sanity checks and wrapping it with various log entries. func (d *Downloader) Synchronise(id string, head common.Hash, td *big.Int, mode SyncMode) error { err := d.synchronise(id, head, td, mode) diff --git a/eth/ethconfig/config.go b/eth/ethconfig/config.go index 8d032260a7..29bb597410 100644 --- a/eth/ethconfig/config.go +++ b/eth/ethconfig/config.go @@ -144,12 +144,14 @@ type Config struct { EthDiscoveryURLs []string SnapDiscoveryURLs []string TrustDiscoveryURLs []string + BscDiscoveryURLs []string NoPruning bool // Whether to disable pruning and flush everything to disk DirectBroadcast bool DisableSnapProtocol bool //Whether disable snap protocol DisableDiffProtocol bool //Whether disable diff protocol EnableTrustProtocol bool //Whether enable trust protocol + DisableBscProtocol bool //Whether disable bsc protocol DiffSync bool // Whether support diff sync PipeCommit bool RangeLimit bool diff --git a/eth/ethconfig/gen_config.go b/eth/ethconfig/gen_config.go index c0d44ce141..13891c04c9 100644 --- a/eth/ethconfig/gen_config.go +++ b/eth/ethconfig/gen_config.go @@ -18,64 +18,66 @@ import ( // MarshalTOML marshals as TOML. func (c Config) MarshalTOML() (interface{}, error) { type Config struct { - Genesis *core.Genesis `toml:",omitempty"` - NetworkId uint64 - SyncMode downloader.SyncMode - DisablePeerTxBroadcast bool - EthDiscoveryURLs []string - SnapDiscoveryURLs []string - TrustDiscoveryURLs []string - NoPruning bool - NoPrefetch bool - DirectBroadcast bool - DisableSnapProtocol bool - DisableDiffProtocol bool - EnableTrustProtocol bool - DiffSync bool - RangeLimit bool - TxLookupLimit uint64 `toml:",omitempty"` - Whitelist map[uint64]common.Hash `toml:"-"` - LightServ int `toml:",omitempty"` - LightIngress int `toml:",omitempty"` - LightEgress int `toml:",omitempty"` - LightPeers int `toml:",omitempty"` - LightNoPrune bool `toml:",omitempty"` - LightNoSyncServe bool `toml:",omitempty"` - SyncFromCheckpoint bool `toml:",omitempty"` - UltraLightServers []string `toml:",omitempty"` - UltraLightFraction int `toml:",omitempty"` - UltraLightOnlyAnnounce bool `toml:",omitempty"` - SkipBcVersionCheck bool `toml:"-"` - DatabaseHandles int `toml:"-"` - DatabaseCache int - DatabaseFreezer string - DatabaseDiff string - TrieCleanCache int - TrieCleanCacheJournal string `toml:",omitempty"` - TrieCleanCacheRejournal time.Duration `toml:",omitempty"` - TrieDirtyCache int - TrieTimeout time.Duration - SnapshotCache int - TriesInMemory uint64 - TriesVerifyMode core.VerifyMode - Preimages bool - PersistDiff bool - DiffBlock uint64 `toml:",omitempty"` - PruneAncientData bool - Miner miner.Config - Ethash ethash.Config `toml:",omitempty"` - TxPool core.TxPoolConfig - GPO gasprice.Config - EnablePreimageRecording bool - DocRoot string `toml:"-"` - EWASMInterpreter string - EVMInterpreter string - RPCGasCap uint64 - RPCEVMTimeout time.Duration - RPCTxFeeCap float64 - Checkpoint *params.TrustedCheckpoint `toml:",omitempty"` - CheckpointOracle *params.CheckpointOracleConfig `toml:",omitempty"` - OverrideBerlin *big.Int `toml:",omitempty"` + Genesis *core.Genesis `toml:",omitempty"` + NetworkId uint64 + SyncMode downloader.SyncMode + DisablePeerTxBroadcast bool + EthDiscoveryURLs []string + SnapDiscoveryURLs []string + TrustDiscoveryURLs []string + BscDiscoveryURLs []string + NoPruning bool + NoPrefetch bool + DirectBroadcast bool + DisableSnapProtocol bool + DisableDiffProtocol bool + EnableTrustProtocol bool + DisableBscProtocol bool + DiffSync bool + RangeLimit bool + TxLookupLimit uint64 `toml:",omitempty"` + Whitelist map[uint64]common.Hash `toml:"-"` + LightServ int `toml:",omitempty"` + LightIngress int `toml:",omitempty"` + LightEgress int `toml:",omitempty"` + LightPeers int `toml:",omitempty"` + LightNoPrune bool `toml:",omitempty"` + LightNoSyncServe bool `toml:",omitempty"` + SyncFromCheckpoint bool `toml:",omitempty"` + UltraLightServers []string `toml:",omitempty"` + UltraLightFraction int `toml:",omitempty"` + UltraLightOnlyAnnounce bool `toml:",omitempty"` + SkipBcVersionCheck bool `toml:"-"` + DatabaseHandles int `toml:"-"` + DatabaseCache int + DatabaseFreezer string + DatabaseDiff string + TrieCleanCache int + TrieCleanCacheJournal string `toml:",omitempty"` + TrieCleanCacheRejournal time.Duration `toml:",omitempty"` + TrieDirtyCache int + TrieTimeout time.Duration + SnapshotCache int + TriesInMemory uint64 + TriesVerifyMode core.VerifyMode + Preimages bool + PersistDiff bool + DiffBlock uint64 `toml:",omitempty"` + PruneAncientData bool + Miner miner.Config + Ethash ethash.Config `toml:",omitempty"` + TxPool core.TxPoolConfig + GPO gasprice.Config + EnablePreimageRecording bool + DocRoot string `toml:"-"` + EWASMInterpreter string + EVMInterpreter string + RPCGasCap uint64 + RPCEVMTimeout time.Duration + RPCTxFeeCap float64 + Checkpoint *params.TrustedCheckpoint `toml:",omitempty"` + CheckpointOracle *params.CheckpointOracleConfig `toml:",omitempty"` + OverrideBerlin *big.Int `toml:",omitempty"` OverrideArrowGlacier *big.Int `toml:",omitempty"` OverrideTerminalTotalDifficulty *big.Int `toml:",omitempty"` } @@ -87,11 +89,13 @@ func (c Config) MarshalTOML() (interface{}, error) { enc.EthDiscoveryURLs = c.EthDiscoveryURLs enc.SnapDiscoveryURLs = c.SnapDiscoveryURLs enc.TrustDiscoveryURLs = c.TrustDiscoveryURLs + enc.BscDiscoveryURLs = c.BscDiscoveryURLs enc.NoPruning = c.NoPruning enc.DirectBroadcast = c.DirectBroadcast enc.DisableSnapProtocol = c.DisableSnapProtocol enc.DisableDiffProtocol = c.DisableDiffProtocol enc.EnableTrustProtocol = c.EnableTrustProtocol + enc.DisableBscProtocol = c.DisableBscProtocol enc.DiffSync = c.DiffSync enc.RangeLimit = c.RangeLimit enc.TxLookupLimit = c.TxLookupLimit @@ -145,64 +149,66 @@ 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"` - NetworkId *uint64 - SyncMode *downloader.SyncMode - DisablePeerTxBroadcast *bool - EthDiscoveryURLs []string - SnapDiscoveryURLs []string - TrustDiscoveryURLs []string - NoPruning *bool - NoPrefetch *bool - DirectBroadcast *bool - DisableSnapProtocol *bool - DisableDiffProtocol *bool - EnableTrustProtocol *bool - DiffSync *bool - RangeLimit *bool - TxLookupLimit *uint64 `toml:",omitempty"` - Whitelist map[uint64]common.Hash `toml:"-"` - LightServ *int `toml:",omitempty"` - LightIngress *int `toml:",omitempty"` - LightEgress *int `toml:",omitempty"` - LightPeers *int `toml:",omitempty"` - LightNoPrune *bool `toml:",omitempty"` - LightNoSyncServe *bool `toml:",omitempty"` - SyncFromCheckpoint *bool `toml:",omitempty"` - UltraLightServers []string `toml:",omitempty"` - UltraLightFraction *int `toml:",omitempty"` - UltraLightOnlyAnnounce *bool `toml:",omitempty"` - SkipBcVersionCheck *bool `toml:"-"` - DatabaseHandles *int `toml:"-"` - DatabaseCache *int - DatabaseFreezer *string - DatabaseDiff *string - PersistDiff *bool - DiffBlock *uint64 `toml:",omitempty"` - PruneAncientData *bool - TrieCleanCache *int - TrieCleanCacheJournal *string `toml:",omitempty"` - TrieCleanCacheRejournal *time.Duration `toml:",omitempty"` - TrieDirtyCache *int - TrieTimeout *time.Duration - SnapshotCache *int - TriesInMemory *uint64 - TriesVerifyMode *core.VerifyMode - Preimages *bool - Miner *miner.Config - Ethash *ethash.Config `toml:",omitempty"` - TxPool *core.TxPoolConfig - GPO *gasprice.Config - EnablePreimageRecording *bool - DocRoot *string `toml:"-"` - EWASMInterpreter *string - EVMInterpreter *string - RPCGasCap *uint64 + Genesis *core.Genesis `toml:",omitempty"` + NetworkId *uint64 + SyncMode *downloader.SyncMode + DisablePeerTxBroadcast *bool + EthDiscoveryURLs []string + SnapDiscoveryURLs []string + TrustDiscoveryURLs []string + BscDiscoveryURLs []string + NoPruning *bool + NoPrefetch *bool + DirectBroadcast *bool + DisableSnapProtocol *bool + DisableDiffProtocol *bool + EnableTrustProtocol *bool + DisableBscProtocol *bool + DiffSync *bool + RangeLimit *bool + TxLookupLimit *uint64 `toml:",omitempty"` + Whitelist map[uint64]common.Hash `toml:"-"` + LightServ *int `toml:",omitempty"` + LightIngress *int `toml:",omitempty"` + LightEgress *int `toml:",omitempty"` + LightPeers *int `toml:",omitempty"` + LightNoPrune *bool `toml:",omitempty"` + LightNoSyncServe *bool `toml:",omitempty"` + SyncFromCheckpoint *bool `toml:",omitempty"` + UltraLightServers []string `toml:",omitempty"` + UltraLightFraction *int `toml:",omitempty"` + UltraLightOnlyAnnounce *bool `toml:",omitempty"` + SkipBcVersionCheck *bool `toml:"-"` + DatabaseHandles *int `toml:"-"` + DatabaseCache *int + DatabaseFreezer *string + DatabaseDiff *string + PersistDiff *bool + DiffBlock *uint64 `toml:",omitempty"` + PruneAncientData *bool + TrieCleanCache *int + TrieCleanCacheJournal *string `toml:",omitempty"` + TrieCleanCacheRejournal *time.Duration `toml:",omitempty"` + TrieDirtyCache *int + TrieTimeout *time.Duration + SnapshotCache *int + TriesInMemory *uint64 + TriesVerifyMode *core.VerifyMode + Preimages *bool + Miner *miner.Config + Ethash *ethash.Config `toml:",omitempty"` + TxPool *core.TxPoolConfig + GPO *gasprice.Config + EnablePreimageRecording *bool + DocRoot *string `toml:"-"` + EWASMInterpreter *string + EVMInterpreter *string + RPCGasCap *uint64 RPCEVMTimeout *time.Duration - RPCTxFeeCap *float64 - Checkpoint *params.TrustedCheckpoint `toml:",omitempty"` - CheckpointOracle *params.CheckpointOracleConfig `toml:",omitempty"` - OverrideBerlin *big.Int `toml:",omitempty"` + RPCTxFeeCap *float64 + Checkpoint *params.TrustedCheckpoint `toml:",omitempty"` + CheckpointOracle *params.CheckpointOracleConfig `toml:",omitempty"` + OverrideBerlin *big.Int `toml:",omitempty"` OverrideArrowGlacier *big.Int `toml:",omitempty"` OverrideTerminalTotalDifficulty *big.Int `toml:",omitempty"` } @@ -231,6 +237,9 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { if dec.TrustDiscoveryURLs != nil { c.TrustDiscoveryURLs = dec.TrustDiscoveryURLs } + if dec.BscDiscoveryURLs != nil { + c.BscDiscoveryURLs = dec.BscDiscoveryURLs + } if dec.NoPruning != nil { c.NoPruning = *dec.NoPruning } @@ -246,6 +255,9 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { if dec.EnableTrustProtocol != nil { c.EnableTrustProtocol = *dec.EnableTrustProtocol } + if dec.DisableBscProtocol != nil { + c.DisableBscProtocol = *dec.DisableBscProtocol + } if dec.DiffSync != nil { c.DiffSync = *dec.DiffSync } diff --git a/eth/fetcher/tx_fetcher.go b/eth/fetcher/tx_fetcher.go index 6cdb5b8804..20eaada986 100644 --- a/eth/fetcher/tx_fetcher.go +++ b/eth/fetcher/tx_fetcher.go @@ -261,7 +261,7 @@ func (f *TxFetcher) Notify(peer string, hashes []common.Hash) error { // Enqueue imports a batch of received transaction into the transaction pool // and the fetcher. This method may be called by both transaction broadcasts and // direct request replies. The differentiation is important so the fetcher can -// re-shedule missing transactions as soon as possible. +// re-schedule missing transactions as soon as possible. func (f *TxFetcher) Enqueue(peer string, txs []*types.Transaction, direct bool) error { // Keep track of all the propagated transactions if direct { diff --git a/eth/filters/api.go b/eth/filters/api.go index 56ee044274..0cacd2cf39 100644 --- a/eth/filters/api.go +++ b/eth/filters/api.go @@ -171,6 +171,68 @@ func (api *PublicFilterAPI) NewPendingTransactions(ctx context.Context) (*rpc.Su return rpcSub, nil } +// NewVotesFilter creates a filter that fetches votes that entered the vote pool. +// It is part of the filter package since polling goes with eth_getFilterChanges. +func (api *PublicFilterAPI) NewVotesFilter() rpc.ID { + var ( + votes = make(chan *types.VoteEnvelope) + voteSub = api.events.SubscribeNewVotes(votes) + ) + api.filtersMu.Lock() + api.filters[voteSub.ID] = &filter{typ: VotesSubscription, deadline: time.NewTimer(api.timeout), hashes: make([]common.Hash, 0), s: voteSub} + api.filtersMu.Unlock() + + gopool.Submit(func() { + for { + select { + case vote := <-votes: + api.filtersMu.Lock() + if f, found := api.filters[voteSub.ID]; found { + f.hashes = append(f.hashes, vote.Hash()) + } + api.filtersMu.Unlock() + case <-voteSub.Err(): + api.filtersMu.Lock() + delete(api.filters, voteSub.ID) + api.filtersMu.Unlock() + return + } + } + }) + + return voteSub.ID +} + +// NewVotes creates a subscription that is triggered each time a vote enters the vote pool. +func (api *PublicFilterAPI) NewVotes(ctx context.Context) (*rpc.Subscription, error) { + notifier, supported := rpc.NotifierFromContext(ctx) + if !supported { + return &rpc.Subscription{}, rpc.ErrNotificationsUnsupported + } + + rpcSub := notifier.CreateSubscription() + + gopool.Submit(func() { + votes := make(chan *types.VoteEnvelope, 128) + voteSub := api.events.SubscribeNewVotes(votes) + + for { + select { + case vote := <-votes: + notifier.Notify(rpcSub.ID, vote) + case <-rpcSub.Err(): + voteSub.Unsubscribe() + return + case <-notifier.Closed(): + voteSub.Unsubscribe() + return + } + } + }) + + return rpcSub, nil +} + // NewBlockFilter creates a filter that fetches blocks that are imported into the chain. // It is part of the filter package since polling goes with eth_getFilterChanges. // @@ -236,6 +298,68 @@ func (api *PublicFilterAPI) NewHeads(ctx context.Context) (*rpc.Subscription, er return rpcSub, nil } +// NewFinalizedHeaderFilter creates a filter that fetches finalized headers that are reached. +func (api *PublicFilterAPI) NewFinalizedHeaderFilter() rpc.ID { + var ( + headers = make(chan *types.Header) + headerSub = api.events.SubscribeNewFinalizedHeaders(headers) + ) + + api.filtersMu.Lock() + api.filters[headerSub.ID] = &filter{typ: FinalizedHeadersSubscription, deadline: time.NewTimer(api.timeout), hashes: make([]common.Hash, 0), s: headerSub} + api.filtersMu.Unlock() + + gopool.Submit(func() { + for { + select { + case h := <-headers: + api.filtersMu.Lock() + if f, found := api.filters[headerSub.ID]; found { + f.hashes = append(f.hashes, h.Hash()) + } + api.filtersMu.Unlock() + case <-headerSub.Err(): + api.filtersMu.Lock() + delete(api.filters, headerSub.ID) + api.filtersMu.Unlock() + return + } + } + }) + + return headerSub.ID +} + +// NewFinalizedHeaders send a notification each time a new finalized header is reached. +func (api *PublicFilterAPI) NewFinalizedHeaders(ctx context.Context) (*rpc.Subscription, error) { + notifier, supported := rpc.NotifierFromContext(ctx) + if !supported { + return &rpc.Subscription{}, rpc.ErrNotificationsUnsupported + } + + rpcSub := notifier.CreateSubscription() + + gopool.Submit(func() { + headers := make(chan *types.Header) + headersSub := api.events.SubscribeNewFinalizedHeaders(headers) + + for { + select { + case h := <-headers: + notifier.Notify(rpcSub.ID, h) + case <-rpcSub.Err(): + headersSub.Unsubscribe() + return + case <-notifier.Closed(): + headersSub.Unsubscribe() + return + } + } + }) + + return rpcSub, nil +} + // Logs creates a subscription that fires for all new log that match the given filter criteria. func (api *PublicFilterAPI) Logs(ctx context.Context, crit FilterCriteria) (*rpc.Subscription, error) { notifier, supported := rpc.NotifierFromContext(ctx) @@ -427,7 +551,7 @@ func (api *PublicFilterAPI) GetFilterChanges(id rpc.ID) (interface{}, error) { f.deadline.Reset(api.timeout) switch f.typ { - case PendingTransactionsSubscription, BlocksSubscription: + case PendingTransactionsSubscription, BlocksSubscription, VotesSubscription: hashes := f.hashes f.hashes = nil return returnHashes(hashes), nil diff --git a/eth/filters/filter.go b/eth/filters/filter.go index 2762993dad..40668cb2ee 100644 --- a/eth/filters/filter.go +++ b/eth/filters/filter.go @@ -19,7 +19,6 @@ package filters import ( "context" "errors" - "fmt" "math/big" "github.com/ethereum/go-ethereum/common" @@ -43,9 +42,11 @@ type Backend interface { SubscribeNewTxsEvent(chan<- core.NewTxsEvent) event.Subscription SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription + SubscribeFinalizedHeaderEvent(ch chan<- core.FinalizedHeaderEvent) event.Subscription SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent) event.Subscription SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscription SubscribePendingLogsEvent(ch chan<- []*types.Log) event.Subscription + SubscribeNewVoteEvent(chan<- core.NewVoteEvent) event.Subscription BloomStatus() (uint64, uint64) ServiceFilter(ctx context.Context, session *bloombits.MatcherSession) @@ -148,23 +149,44 @@ func (f *Filter) Logs(ctx context.Context) ([]*types.Log, error) { return nil, nil } var ( - head = header.Number.Uint64() - end = uint64(f.end) + err error + head = header.Number.Int64() pending = f.end == rpc.PendingBlockNumber.Int64() ) - if f.begin == rpc.LatestBlockNumber.Int64() { - f.begin = int64(head) + resolveSpecial := func(number int64) (int64, error) { + var hdr *types.Header + switch number { + case rpc.LatestBlockNumber.Int64(): + return head, nil + case rpc.PendingBlockNumber.Int64(): + // we should return head here since we've already captured + // that we need to get the pending logs in the pending boolean above + return head, nil + case rpc.FinalizedBlockNumber.Int64(): + hdr, _ = f.backend.HeaderByNumber(ctx, rpc.FinalizedBlockNumber) + if hdr == nil { + return 0, errors.New("finalized header not found") + } + case rpc.SafeBlockNumber.Int64(): + hdr, _ = f.backend.HeaderByNumber(ctx, rpc.SafeBlockNumber) + if hdr == nil { + return 0, errors.New("safe header not found") + } + default: + return number, nil + } + return hdr.Number.Int64(), nil } - if f.end == rpc.LatestBlockNumber.Int64() || f.end == rpc.PendingBlockNumber.Int64() { - end = head + if f.begin, err = resolveSpecial(f.begin); err != nil { + return nil, err } - if f.rangeLimit && (int64(end)-f.begin) > maxFilterBlockRange { - return nil, fmt.Errorf("exceed maximum block range: %d", maxFilterBlockRange) + if f.end, err = resolveSpecial(f.end); err != nil { + return nil, err } // Gather all indexed logs, and finish with non indexed ones var ( logs []*types.Log - err error + end = uint64(f.end) size, sections = f.backend.BloomStatus() ) if indexed := sections * size; indexed > uint64(f.begin) { diff --git a/eth/filters/filter_system.go b/eth/filters/filter_system.go index 12f037d0f9..bf461a1c5c 100644 --- a/eth/filters/filter_system.go +++ b/eth/filters/filter_system.go @@ -52,7 +52,11 @@ const ( PendingTransactionsSubscription // BlocksSubscription queries hashes for blocks that are imported BlocksSubscription - // LastSubscription keeps track of the last index + // VotesSubscription queries vote hashes for votes entering the vote pool + VotesSubscription + // FinalizedHeadersSubscription queries hashes for finalized headers that are reached + FinalizedHeadersSubscription + // LastIndexSubscription keeps track of the last index LastIndexSubscription ) @@ -66,18 +70,25 @@ const ( logsChanSize = 10 // chainEvChanSize is the size of channel listening to ChainEvent. chainEvChanSize = 10 + // finalizedHeaderEvChanSize is the size of channel listening to FinalizedHeaderEvent. + finalizedHeaderEvChanSize = 10 + // voteChanSize is the size of channel listening to NewVoteEvent. + // The number is referenced from the size of vote pool. + voteChanSize = 256 ) type subscription struct { - id rpc.ID - typ Type - created time.Time - logsCrit ethereum.FilterQuery - logs chan []*types.Log - hashes chan []common.Hash - headers chan *types.Header - installed chan struct{} // closed when the filter is installed - err chan error // closed when the filter is uninstalled + id rpc.ID + typ Type + created time.Time + logsCrit ethereum.FilterQuery + logs chan []*types.Log + hashes chan []common.Hash + headers chan *types.Header + finalizedHeaders chan *types.Header + votes chan *types.VoteEnvelope + installed chan struct{} // closed when the filter is installed + err chan error // closed when the filter is uninstalled } // EventSystem creates subscriptions, processes events and broadcasts them to the @@ -88,20 +99,24 @@ type EventSystem struct { lastHead *types.Header // Subscriptions - txsSub event.Subscription // Subscription for new transaction event - logsSub event.Subscription // Subscription for new log event - rmLogsSub event.Subscription // Subscription for removed log event - pendingLogsSub event.Subscription // Subscription for pending log event - chainSub event.Subscription // Subscription for new chain event + txsSub event.Subscription // Subscription for new transaction event + logsSub event.Subscription // Subscription for new log event + rmLogsSub event.Subscription // Subscription for removed log event + pendingLogsSub event.Subscription // Subscription for pending log event + chainSub event.Subscription // Subscription for new chain event + finalizedHeaderSub event.Subscription // Subscription for new finalized header + voteSub event.Subscription // Subscription for new vote event // Channels - install chan *subscription // install filter for event notification - uninstall chan *subscription // remove filter for event notification - txsCh chan core.NewTxsEvent // Channel to receive new transactions event - logsCh chan []*types.Log // Channel to receive new log event - pendingLogsCh chan []*types.Log // Channel to receive new log event - rmLogsCh chan core.RemovedLogsEvent // Channel to receive removed log event - chainCh chan core.ChainEvent // Channel to receive new chain event + install chan *subscription // install filter for event notification + uninstall chan *subscription // remove filter for event notification + txsCh chan core.NewTxsEvent // Channel to receive new transactions event + logsCh chan []*types.Log // Channel to receive new log event + pendingLogsCh chan []*types.Log // Channel to receive new log event + rmLogsCh chan core.RemovedLogsEvent // Channel to receive removed log event + chainCh chan core.ChainEvent // Channel to receive new chain event + finalizedHeaderCh chan core.FinalizedHeaderEvent // Channel to receive new finalized header event + voteCh chan core.NewVoteEvent // Channel to receive new vote event } // NewEventSystem creates a new manager that listens for event on the given mux, @@ -112,15 +127,17 @@ type EventSystem struct { // or by stopping the given mux. func NewEventSystem(backend Backend, lightMode bool) *EventSystem { m := &EventSystem{ - backend: backend, - lightMode: lightMode, - install: make(chan *subscription), - uninstall: make(chan *subscription), - txsCh: make(chan core.NewTxsEvent, txChanSize), - logsCh: make(chan []*types.Log, logsChanSize), - rmLogsCh: make(chan core.RemovedLogsEvent, rmLogsChanSize), - pendingLogsCh: make(chan []*types.Log, logsChanSize), - chainCh: make(chan core.ChainEvent, chainEvChanSize), + backend: backend, + lightMode: lightMode, + install: make(chan *subscription), + uninstall: make(chan *subscription), + txsCh: make(chan core.NewTxsEvent, txChanSize), + logsCh: make(chan []*types.Log, logsChanSize), + rmLogsCh: make(chan core.RemovedLogsEvent, rmLogsChanSize), + pendingLogsCh: make(chan []*types.Log, logsChanSize), + chainCh: make(chan core.ChainEvent, chainEvChanSize), + finalizedHeaderCh: make(chan core.FinalizedHeaderEvent, finalizedHeaderEvChanSize), + voteCh: make(chan core.NewVoteEvent, voteChanSize), } // Subscribe events @@ -129,11 +146,16 @@ func NewEventSystem(backend Backend, lightMode bool) *EventSystem { m.rmLogsSub = m.backend.SubscribeRemovedLogsEvent(m.rmLogsCh) m.chainSub = m.backend.SubscribeChainEvent(m.chainCh) m.pendingLogsSub = m.backend.SubscribePendingLogsEvent(m.pendingLogsCh) + m.finalizedHeaderSub = m.backend.SubscribeFinalizedHeaderEvent(m.finalizedHeaderCh) + m.voteSub = m.backend.SubscribeNewVoteEvent(m.voteCh) // Make sure none of the subscriptions are empty if m.txsSub == nil || m.logsSub == nil || m.rmLogsSub == nil || m.chainSub == nil || m.pendingLogsSub == nil { log.Crit("Subscribe for event system failed") } + if m.voteSub == nil || m.finalizedHeaderSub == nil { + log.Warn("Subscribe for vote or finalized header event failed") + } go m.eventLoop() return m @@ -167,6 +189,7 @@ func (sub *Subscription) Unsubscribe() { case <-sub.f.logs: case <-sub.f.hashes: case <-sub.f.headers: + case <-sub.f.votes: } } @@ -234,6 +257,7 @@ func (es *EventSystem) subscribeMinedPendingLogs(crit ethereum.FilterQuery, logs logs: logs, hashes: make(chan []common.Hash), headers: make(chan *types.Header), + votes: make(chan *types.VoteEnvelope), installed: make(chan struct{}), err: make(chan error), } @@ -251,6 +275,7 @@ func (es *EventSystem) subscribeLogs(crit ethereum.FilterQuery, logs chan []*typ logs: logs, hashes: make(chan []common.Hash), headers: make(chan *types.Header), + votes: make(chan *types.VoteEnvelope), installed: make(chan struct{}), err: make(chan error), } @@ -268,6 +293,7 @@ func (es *EventSystem) subscribePendingLogs(crit ethereum.FilterQuery, logs chan logs: logs, hashes: make(chan []common.Hash), headers: make(chan *types.Header), + votes: make(chan *types.VoteEnvelope), installed: make(chan struct{}), err: make(chan error), } @@ -284,6 +310,24 @@ func (es *EventSystem) SubscribeNewHeads(headers chan *types.Header) *Subscripti logs: make(chan []*types.Log), hashes: make(chan []common.Hash), headers: headers, + votes: make(chan *types.VoteEnvelope), + installed: make(chan struct{}), + err: make(chan error), + } + return es.subscribe(sub) +} + +// SubscribeNewFinalizedHeaders creates a subscription that writes the finalized header of a block that is +// reached recently. +func (es *EventSystem) SubscribeNewFinalizedHeaders(headers chan *types.Header) *Subscription { + sub := &subscription{ + id: rpc.NewID(), + typ: FinalizedHeadersSubscription, + created: time.Now(), + logs: make(chan []*types.Log), + hashes: make(chan []common.Hash), + headers: headers, + votes: make(chan *types.VoteEnvelope), installed: make(chan struct{}), err: make(chan error), } @@ -300,6 +344,24 @@ func (es *EventSystem) SubscribePendingTxs(hashes chan []common.Hash) *Subscript logs: make(chan []*types.Log), hashes: hashes, headers: make(chan *types.Header), + votes: make(chan *types.VoteEnvelope), + installed: make(chan struct{}), + err: make(chan error), + } + return es.subscribe(sub) +} + +// SubscribeNewVotes creates a subscription that writes transaction hashes for +// transactions that enter the transaction pool. +func (es *EventSystem) SubscribeNewVotes(votes chan *types.VoteEnvelope) *Subscription { + sub := &subscription{ + id: rpc.NewID(), + typ: VotesSubscription, + created: time.Now(), + logs: make(chan []*types.Log), + hashes: make(chan []common.Hash), + headers: make(chan *types.Header), + votes: votes, installed: make(chan struct{}), err: make(chan error), } @@ -351,6 +413,12 @@ func (es *EventSystem) handleTxsEvent(filters filterIndex, ev core.NewTxsEvent) } } +func (es *EventSystem) handleVoteEvent(filters filterIndex, ev core.NewVoteEvent) { + for _, f := range filters[VotesSubscription] { + f.votes <- ev.Vote + } +} + func (es *EventSystem) handleChainEvent(filters filterIndex, ev core.ChainEvent) { for _, f := range filters[BlocksSubscription] { f.headers <- ev.Block.Header() @@ -366,6 +434,12 @@ func (es *EventSystem) handleChainEvent(filters filterIndex, ev core.ChainEvent) } } +func (es *EventSystem) handleFinalizedHeaderEvent(filters filterIndex, ev core.FinalizedHeaderEvent) { + for _, f := range filters[FinalizedHeadersSubscription] { + f.headers <- ev.Header + } +} + func (es *EventSystem) lightFilterNewHead(newHeader *types.Header, callBack func(*types.Header, bool)) { oldh := es.lastHead es.lastHead = newHeader @@ -448,6 +522,10 @@ func (es *EventSystem) eventLoop() { es.rmLogsSub.Unsubscribe() es.pendingLogsSub.Unsubscribe() es.chainSub.Unsubscribe() + es.finalizedHeaderSub.Unsubscribe() + if es.voteSub != nil { + es.voteSub.Unsubscribe() + } }() index := make(filterIndex) @@ -455,6 +533,10 @@ func (es *EventSystem) eventLoop() { index[i] = make(map[rpc.ID]*subscription) } + var voteSubErr <-chan error + if es.voteSub != nil { + voteSubErr = es.voteSub.Err() + } for { select { case ev := <-es.txsCh: @@ -467,6 +549,10 @@ func (es *EventSystem) eventLoop() { es.handlePendingLogs(index, ev) case ev := <-es.chainCh: es.handleChainEvent(index, ev) + case ev := <-es.finalizedHeaderCh: + es.handleFinalizedHeaderEvent(index, ev) + case ev := <-es.voteCh: + es.handleVoteEvent(index, ev) case f := <-es.install: if f.typ == MinedAndPendingLogsSubscription { @@ -497,6 +583,10 @@ func (es *EventSystem) eventLoop() { return case <-es.chainSub.Err(): return + case <-es.finalizedHeaderSub.Err(): + return + case <-voteSubErr: + return } } } diff --git a/eth/filters/filter_system_test.go b/eth/filters/filter_system_test.go index 7435a19e86..737eaa17c7 100644 --- a/eth/filters/filter_system_test.go +++ b/eth/filters/filter_system_test.go @@ -18,6 +18,7 @@ package filters import ( "context" + "errors" "fmt" "math/big" "math/rand" @@ -44,14 +45,16 @@ var ( ) type testBackend struct { - mux *event.TypeMux - db ethdb.Database - sections uint64 - txFeed event.Feed - logsFeed event.Feed - rmLogsFeed event.Feed - pendingLogsFeed event.Feed - chainFeed event.Feed + mux *event.TypeMux + db ethdb.Database + sections uint64 + txFeed event.Feed + logsFeed event.Feed + rmLogsFeed event.Feed + pendingLogsFeed event.Feed + chainFeed event.Feed + finalizedHeaderFeed event.Feed + voteFeed event.Feed } func (b *testBackend) ChainDb() ethdb.Database { @@ -63,14 +66,19 @@ func (b *testBackend) HeaderByNumber(ctx context.Context, blockNr rpc.BlockNumbe hash common.Hash num uint64 ) - if blockNr == rpc.LatestBlockNumber { + switch blockNr { + case rpc.LatestBlockNumber: hash = rawdb.ReadHeadBlockHash(b.db) number := rawdb.ReadHeaderNumber(b.db, hash) if number == nil { return nil, nil } num = *number - } else { + case rpc.FinalizedBlockNumber: + return nil, errors.New("finalized block not found") + case rpc.SafeBlockNumber: + return nil, errors.New("safe block not found") + default: num = uint64(blockNr) hash = rawdb.ReadCanonicalHash(b.db, num) } @@ -130,6 +138,14 @@ func (b *testBackend) SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subsc return b.chainFeed.Subscribe(ch) } +func (b *testBackend) SubscribeFinalizedHeaderEvent(ch chan<- core.FinalizedHeaderEvent) event.Subscription { + return b.finalizedHeaderFeed.Subscribe(ch) +} + +func (b *testBackend) SubscribeNewVoteEvent(ch chan<- core.NewVoteEvent) event.Subscription { + return b.voteFeed.Subscribe(ch) +} + func (b *testBackend) BloomStatus() (uint64, uint64) { return params.BloomBitsBlocks, b.sections } @@ -735,3 +751,79 @@ func flattenLogs(pl [][]*types.Log) []*types.Log { } return logs } + +func TestVoteSubscription(t *testing.T) { + t.Parallel() + + var ( + db = rawdb.NewMemoryDatabase() + backend = &testBackend{db: db} + api = NewPublicFilterAPI(backend, false, deadline, false) + votes = []*types.VoteEnvelope{ + &types.VoteEnvelope{ + VoteAddress: types.BLSPublicKey{}, + Signature: types.BLSSignature{}, + Data: &types.VoteData{ + SourceNumber: uint64(0), + SourceHash: common.BytesToHash(common.Hex2Bytes(string(rune(0)))), + TargetNumber: uint64(1), + TargetHash: common.BytesToHash(common.Hex2Bytes(string(rune(1)))), + }, + }, + &types.VoteEnvelope{ + VoteAddress: types.BLSPublicKey{}, + Signature: types.BLSSignature{}, + Data: &types.VoteData{ + SourceNumber: uint64(0), + SourceHash: common.BytesToHash(common.Hex2Bytes(string(rune(0)))), + TargetNumber: uint64(2), + TargetHash: common.BytesToHash(common.Hex2Bytes(string(rune(2)))), + }, + }, + &types.VoteEnvelope{ + VoteAddress: types.BLSPublicKey{}, + Signature: types.BLSSignature{}, + Data: &types.VoteData{ + SourceNumber: uint64(0), + SourceHash: common.BytesToHash(common.Hex2Bytes(string(rune(0)))), + TargetNumber: uint64(3), + TargetHash: common.BytesToHash(common.Hex2Bytes(string(rune(3)))), + }, + }, + &types.VoteEnvelope{ + VoteAddress: types.BLSPublicKey{}, + Signature: types.BLSSignature{}, + Data: &types.VoteData{ + SourceNumber: uint64(0), + SourceHash: common.BytesToHash(common.Hex2Bytes(string(rune(0)))), + TargetNumber: uint64(4), + TargetHash: common.BytesToHash(common.Hex2Bytes(string(rune(4)))), + }, + }, + } + ) + + chan0 := make(chan *types.VoteEnvelope) + sub0 := api.events.SubscribeNewVotes(chan0) + + go func() { // simulate client + i := 0 + for i != len(votes) { + vote := <-chan0 + if votes[i].Hash() != vote.Hash() { + t.Errorf("sub received invalid hash on index %d, want %x, got %x", i, votes[i].Hash(), vote.Hash()) + } + i++ + } + + sub0.Unsubscribe() + }() + + time.Sleep(1 * time.Second) + for _, v := range votes { + ev := core.NewVoteEvent{Vote: v} + backend.voteFeed.Send(ev) + } + + <-sub0.Err() +} diff --git a/eth/gasprice/feehistory.go b/eth/gasprice/feehistory.go index 78bade5ae8..ae7d0069a1 100644 --- a/eth/gasprice/feehistory.go +++ b/eth/gasprice/feehistory.go @@ -137,44 +137,68 @@ 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 int) (*types.Block, []*types.Receipt, uint64, int, error) { +func (oracle *Oracle) resolveBlockRange(ctx context.Context, reqEnd rpc.BlockNumber, blocks 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 && latestHeader != 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 } - // ensure not trying to retrieve before genesis - if rpc.BlockNumber(blocks) > lastBlock+1 { - blocks = int(lastBlock + 1) + // Ensure not trying to retrieve before genesis. + if uint64(reqEnd+1) < uint64(blocks) { + 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/gasprice/feehistory_test.go b/eth/gasprice/feehistory_test.go index c259eb0acf..25a685effc 100644 --- a/eth/gasprice/feehistory_test.go +++ b/eth/gasprice/feehistory_test.go @@ -50,6 +50,8 @@ func TestFeeHistory(t *testing.T) { {false, 1000, 1000, 2, rpc.PendingBlockNumber, nil, 32, 1, nil}, {true, 1000, 1000, 2, rpc.PendingBlockNumber, nil, 32, 2, nil}, {true, 1000, 1000, 2, rpc.PendingBlockNumber, []float64{0, 10}, 32, 2, nil}, + // {false, 1000, 1000, 2, rpc.FinalizedBlockNumber, []float64{0, 10}, 24, 2, nil}, + // {false, 1000, 1000, 2, rpc.SafeBlockNumber, []float64{0, 10}, 24, 2, nil}, } for i, c := range cases { config := Config{ diff --git a/eth/gasprice/gasprice_test.go b/eth/gasprice/gasprice_test.go index 01edde38ce..2820cc683d 100644 --- a/eth/gasprice/gasprice_test.go +++ b/eth/gasprice/gasprice_test.go @@ -18,6 +18,7 @@ package gasprice import ( "context" + "errors" "math" "math/big" "testing" @@ -45,6 +46,15 @@ func (b *testBackend) HeaderByNumber(ctx context.Context, number rpc.BlockNumber if number > testHead { return nil, nil } + if number == rpc.EarliestBlockNumber { + number = 0 + } + if number == rpc.FinalizedBlockNumber { + return b.chain.CurrentFinalBlock(), nil + } + if number == rpc.SafeBlockNumber { + return b.chain.CurrentSafeBlock(), nil + } if number == rpc.LatestBlockNumber { number = testHead } @@ -62,6 +72,23 @@ func (b *testBackend) BlockByNumber(ctx context.Context, number rpc.BlockNumber) if number > testHead { return nil, nil } + if number == rpc.EarliestBlockNumber { + number = 0 + } + if number == rpc.FinalizedBlockNumber { + header := b.chain.CurrentFinalBlock() + if header == nil { + return nil, errors.New("finalized block not found") + } + number = rpc.BlockNumber(header.Number.Uint64()) + } + if number == rpc.SafeBlockNumber { + header := b.chain.CurrentSafeBlock() + if header == nil { + return nil, errors.New("safe block not found") + } + number = rpc.BlockNumber(header.Number.Uint64()) + } if number == rpc.LatestBlockNumber { number = testHead } @@ -109,6 +136,8 @@ func newTestBackend(t *testing.T, londonBlock *big.Int, pending bool) *testBacke config.LondonBlock = londonBlock config.ArrowGlacierBlock = londonBlock config.GibbsBlock = nil + config.LubanBlock = nil + config.PlatoBlock = nil engine := ethash.NewFaker() db := rawdb.NewMemoryDatabase() genesis, err := gspec.Commit(db) diff --git a/eth/handler.go b/eth/handler.go index 96971beb44..92e2b78f10 100644 --- a/eth/handler.go +++ b/eth/handler.go @@ -33,6 +33,7 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/eth/downloader" "github.com/ethereum/go-ethereum/eth/fetcher" + "github.com/ethereum/go-ethereum/eth/protocols/bsc" "github.com/ethereum/go-ethereum/eth/protocols/diff" "github.com/ethereum/go-ethereum/eth/protocols/eth" "github.com/ethereum/go-ethereum/eth/protocols/snap" @@ -49,6 +50,12 @@ const ( // txChanSize is the size of channel listening to NewTxsEvent. // The number is referenced from the size of tx pool. txChanSize = 4096 + + // voteChanSize is the size of channel listening to NewVotesEvent. + voteChanSize = 256 + + // deltaTdThreshold is the threshold of TD difference for peers to broadcast votes. + deltaTdThreshold = 20 ) var ( @@ -82,12 +89,24 @@ type txPool interface { SubscribeReannoTxsEvent(chan<- core.ReannoTxsEvent) event.Subscription } +// votePool defines the methods needed from a votes pool implementation to +// support all the operations needed by the Ethereum chain protocols. +type votePool interface { + PutVote(vote *types.VoteEnvelope) + GetVotes() []*types.VoteEnvelope + + // SubscribeNewVoteEvent should return an event subscription of + // NewVotesEvent and send events to the given channel. + SubscribeNewVoteEvent(ch chan<- core.NewVoteEvent) event.Subscription +} + // handlerConfig is the collection of initialization parameters to create a full // node network handler. type handlerConfig struct { - Database ethdb.Database // Database for direct sync insertions - Chain *core.BlockChain // Blockchain to serve data from - TxPool txPool // Transaction pool to propagate from + Database ethdb.Database // Database for direct sync insertions + Chain *core.BlockChain // Blockchain to serve data from + TxPool txPool // Transaction pool to propagate from + VotePool votePool Merger *consensus.Merger // The manager for eth1/2 transition Network uint64 // Network identifier to adfvertise Sync downloader.SyncMode // Whether to snap or full sync @@ -116,6 +135,7 @@ type handler struct { database ethdb.Database txpool txPool + votepool votePool chain *core.BlockChain maxPeers int @@ -131,6 +151,8 @@ type handler struct { reannoTxsCh chan core.ReannoTxsEvent reannoTxsSub event.Subscription minedBlockSub *event.TypeMuxSubscription + voteCh chan core.NewVoteEvent + votesSub event.Subscription whitelist map[uint64]common.Hash @@ -158,6 +180,7 @@ func newHandler(config *handlerConfig) (*handler, error) { eventMux: config.EventMux, database: config.Database, txpool: config.TxPool, + votepool: config.VotePool, chain: config.Chain, peers: config.PeerSet, merger: config.Merger, @@ -306,7 +329,7 @@ func newHandler(config *handlerConfig) (*handler, error) { } // runEthPeer registers an eth peer into the joint eth/snap peerset, adds it to -// various subsistems and starts handling messages. +// various subsystems and starts handling messages. func (h *handler) runEthPeer(peer *eth.Peer, handler eth.Handler) error { // If the peer has a `snap` extension, wait for it to connect so we can have // a uniform initialization/teardown mechanism @@ -325,6 +348,11 @@ func (h *handler) runEthPeer(peer *eth.Peer, handler eth.Handler) error { peer.Log().Error("Trust extension barrier failed", "err", err) return err } + bsc, err := h.peers.waitBscExtension(peer) + if err != nil { + peer.Log().Error("Bsc extension barrier failed", "err", err) + return err + } // TODO(karalabe): Not sure why this is needed if !h.chainSync.handlePeerEvent(peer) { return p2p.DiscQuitting @@ -365,7 +393,7 @@ func (h *handler) runEthPeer(peer *eth.Peer, handler eth.Handler) error { peer.Log().Debug("Ethereum peer connected", "name", peer.Name()) // Register the peer locally - if err := h.peers.registerPeer(peer, snap, diff, trust); err != nil { + if err := h.peers.registerPeer(peer, snap, diff, trust, bsc); err != nil { peer.Log().Error("Ethereum peer registration failed", "err", err) return err } @@ -388,9 +416,12 @@ func (h *handler) runEthPeer(peer *eth.Peer, handler eth.Handler) error { } h.chainSync.handlePeerEvent(peer) - // Propagate existing transactions. new transactions appearing + // Propagate existing transactions and votes. new transactions and votes appearing // after this will be sent via broadcasts. h.syncTransactions(peer) + if h.votepool != nil && p.bscExt != nil { + h.syncVotes(p.bscExt) + } // Create a notification channel for pending requests if the peer goes down dead := make(chan struct{}) @@ -540,6 +571,21 @@ func (h *handler) runTrustExtension(peer *trust.Peer, handler trust.Handler) err return handler(peer) } +// runBscExtension registers a `bsc` peer into the joint eth/bsc peerset and +// starts handling inbound messages. As `bsc` is only a satellite protocol to +// `eth`, all subsystem registrations and lifecycle management will be done by +// the main `eth` handler to prevent strange races. +func (h *handler) runBscExtension(peer *bsc.Peer, handler bsc.Handler) error { + h.peerWG.Add(1) + defer h.peerWG.Done() + + if err := h.peers.registerBscExtension(peer); err != nil { + peer.Log().Error("Bsc extension registration failed", "err", err) + return err + } + return handler(peer) +} + // removePeer requests disconnection of a peer. func (h *handler) removePeer(id string) { peer := h.peers.peer(id) @@ -589,6 +635,14 @@ func (h *handler) Start(maxPeers int) { h.txsSub = h.txpool.SubscribeNewTxsEvent(h.txsCh) go h.txBroadcastLoop() + // broadcast votes + if h.votepool != nil { + h.wg.Add(1) + h.voteCh = make(chan core.NewVoteEvent, voteChanSize) + h.votesSub = h.votepool.SubscribeNewVoteEvent(h.voteCh) + go h.voteBroadcastLoop() + } + // announce local pending transactions again h.wg.Add(1) h.reannoTxsCh = make(chan core.ReannoTxsEvent, txChanSize) @@ -609,6 +663,9 @@ func (h *handler) Stop() { h.txsSub.Unsubscribe() // quits txBroadcastLoop h.reannoTxsSub.Unsubscribe() // quits txReannounceLoop h.minedBlockSub.Unsubscribe() // quits blockBroadcastLoop + if h.votepool != nil { + h.votesSub.Unsubscribe() // quits voteBroadcastLoop + } // Quit chainSync and txsync64. // After this is done, no new peers will be accepted. @@ -741,6 +798,37 @@ func (h *handler) ReannounceTransactions(txs types.Transactions) { "announce packs", peersCount, "announced hashes", peersCount*uint(len(hashes))) } +// BroadcastVote will propagate a batch of votes to all peers +// which are not known to already have the given vote. +func (h *handler) BroadcastVote(vote *types.VoteEnvelope) { + var ( + directCount int // Count of announcements made + directPeers int + + voteMap = make(map[*ethPeer]*types.VoteEnvelope) // Set peer->hash to transfer directly + ) + + // Broadcast vote to a batch of peers not knowing about it + peers := h.peers.peersWithoutVote(vote.Hash()) + headBlock := h.chain.CurrentBlock() + currentTD := h.chain.GetTd(headBlock.Hash(), headBlock.NumberU64()) + for _, peer := range peers { + _, peerTD := peer.Head() + deltaTD := new(big.Int).Abs(new(big.Int).Sub(currentTD, peerTD)) + if deltaTD.Cmp(big.NewInt(deltaTdThreshold)) < 1 && peer.bscExt != nil { + voteMap[peer] = vote + } + } + + for peer, _vote := range voteMap { + directPeers++ + directCount += 1 + votes := []*types.VoteEnvelope{_vote} + peer.bscExt.AsyncSendVotes(votes) + } + log.Debug("Vote broadcast", "vote packs", directPeers, "broadcast vote", directCount) +} + // minedBroadcastLoop sends mined blocks to connected peers. func (h *handler) minedBroadcastLoop() { defer h.wg.Done() @@ -778,3 +866,16 @@ func (h *handler) txReannounceLoop() { } } } + +// voteBroadcastLoop announces new vote to connected peers. +func (h *handler) voteBroadcastLoop() { + defer h.wg.Done() + for { + select { + case event := <-h.voteCh: + h.BroadcastVote(event.Vote) + case <-h.votesSub.Err(): + return + } + } +} diff --git a/eth/handler_bsc.go b/eth/handler_bsc.go new file mode 100644 index 0000000000..fcb39ed1ab --- /dev/null +++ b/eth/handler_bsc.go @@ -0,0 +1,68 @@ +package eth + +import ( + "fmt" + + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/eth/protocols/bsc" + "github.com/ethereum/go-ethereum/p2p/enode" +) + +// bscHandler implements the bsc.Backend interface to handle the various network +// packets that are sent as broadcasts. +type bscHandler handler + +func (h *bscHandler) Chain() *core.BlockChain { return h.chain } + +// RunPeer is invoked when a peer joins on the `bsc` protocol. +func (h *bscHandler) RunPeer(peer *bsc.Peer, hand bsc.Handler) error { + if err := peer.Handshake(); err != nil { + // ensure that waitBscExtension receives the exit signal normally + // otherwise, can't graceful shutdown + ps := h.peers + id := peer.ID() + + // Ensure nobody can double connect + ps.lock.Lock() + if wait, ok := ps.bscWait[id]; ok { + delete(ps.bscWait, id) + wait <- nil + } + ps.lock.Unlock() + return err + } + return (*handler)(h).runBscExtension(peer, hand) +} + +// PeerInfo retrieves all known `bsc` information about a peer. +func (h *bscHandler) PeerInfo(id enode.ID) interface{} { + if p := h.peers.peer(id.String()); p != nil && p.bscExt != nil { + return p.bscExt.info() + } + return nil +} + +// Handle is invoked from a peer's message handler when it receives a new remote +// message that the handler couldn't consume and serve itself. +func (h *bscHandler) Handle(peer *bsc.Peer, packet bsc.Packet) error { + // DeliverSnapPacket is invoked from a peer's message handler when it transmits a + // data packet for the local node to consume. + switch packet := packet.(type) { + case *bsc.VotesPacket: + return h.handleVotesBroadcast(peer, packet.Votes) + + default: + return fmt.Errorf("unexpected bsc packet type: %T", packet) + } +} + +// handleVotesBroadcast is invoked from a peer's message handler when it transmits a +// votes broadcast for the local node to process. +func (h *bscHandler) handleVotesBroadcast(peer *bsc.Peer, votes []*types.VoteEnvelope) error { + // Try to put votes into votepool + for _, vote := range votes { + h.votepool.PutVote(vote) + } + return nil +} diff --git a/eth/handler_bsc_test.go b/eth/handler_bsc_test.go new file mode 100644 index 0000000000..932826a886 --- /dev/null +++ b/eth/handler_bsc_test.go @@ -0,0 +1,276 @@ +package eth + +import ( + "fmt" + "testing" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/forkid" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/eth/protocols/bsc" + "github.com/ethereum/go-ethereum/eth/protocols/eth" + "github.com/ethereum/go-ethereum/event" + "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/p2p/enode" +) + +type testBscHandler struct { + voteBroadcasts event.Feed +} + +func (h *testBscHandler) Chain() *core.BlockChain { panic("no backing chain") } +func (h *testBscHandler) RunPeer(peer *bsc.Peer, handler bsc.Handler) error { + panic("not used in tests") +} +func (h *testBscHandler) PeerInfo(enode.ID) interface{} { panic("not used in tests") } +func (h *testBscHandler) Handle(peer *bsc.Peer, packet bsc.Packet) error { + switch packet := packet.(type) { + case *bsc.VotesPacket: + h.voteBroadcasts.Send(packet.Votes) + return nil + + default: + panic(fmt.Sprintf("unexpected bsc packet type in tests: %T", packet)) + } +} + +func TestSendVotes67(t *testing.T) { testSendVotes(t, eth.ETH67) } + +func testSendVotes(t *testing.T, protocol uint) { + t.Parallel() + + // Create a message handler and fill the pool with big votes + handler := newTestHandler() + defer handler.close() + + insert := make([]*types.VoteEnvelope, 100) + for index := range insert { + vote := types.VoteEnvelope{ + VoteAddress: types.BLSPublicKey{}, + Signature: types.BLSSignature{}, + Data: &types.VoteData{ + SourceNumber: uint64(0), + SourceHash: common.BytesToHash(common.Hex2Bytes(string(rune(0)))), + TargetNumber: uint64(index), + TargetHash: common.BytesToHash(common.Hex2Bytes(string(rune(index)))), + }, + } + insert[index] = &vote + go handler.votepool.PutVote(&vote) + } + time.Sleep(250 * time.Millisecond) // Wait until vote events get out of the system (can't use events, vote broadcaster races with peer join) + + protos := []p2p.Protocol{ + { + Name: "eth", + Version: eth.ETH66, + }, + { + Name: "eth", + Version: eth.ETH67, + }, + { + Name: "bsc", + Version: bsc.Bsc1, + }, + } + caps := []p2p.Cap{ + { + Name: "eth", + Version: eth.ETH66, + }, + { + Name: "eth", + Version: eth.ETH67, + }, + { + Name: "bsc", + Version: bsc.Bsc1, + }, + } + + // Create a source handler to send messages through and a sink peer to receive them + p2pEthSrc, p2pEthSink := p2p.MsgPipe() + defer p2pEthSrc.Close() + defer p2pEthSink.Close() + + localEth := eth.NewPeer(protocol, p2p.NewPeerWithProtocols(enode.ID{1}, protos, "", caps), p2pEthSrc, nil) + remoteEth := eth.NewPeer(protocol, p2p.NewPeerWithProtocols(enode.ID{2}, protos, "", caps), p2pEthSink, nil) + defer localEth.Close() + defer remoteEth.Close() + + p2pBscSrc, p2pBscSink := p2p.MsgPipe() + defer p2pBscSrc.Close() + defer p2pBscSink.Close() + + localBsc := bsc.NewPeer(bsc.Bsc1, p2p.NewPeerWithProtocols(enode.ID{1}, protos, "", caps), p2pBscSrc) + remoteBsc := bsc.NewPeer(bsc.Bsc1, p2p.NewPeerWithProtocols(enode.ID{3}, protos, "", caps), p2pBscSink) + defer localBsc.Close() + defer remoteBsc.Close() + + go func(p *bsc.Peer) { + (*bscHandler)(handler.handler).RunPeer(p, func(peer *bsc.Peer) error { + return bsc.Handle((*bscHandler)(handler.handler), peer) + }) + }(localBsc) + + time.Sleep(200 * time.Millisecond) + remoteBsc.Handshake() + + time.Sleep(200 * time.Millisecond) + go func(p *eth.Peer) { + handler.handler.runEthPeer(p, func(peer *eth.Peer) error { + return eth.Handle((*ethHandler)(handler.handler), peer) + }) + }(localEth) + + // Run the handshake locally to avoid spinning up a source handler + var ( + genesis = handler.chain.Genesis() + head = handler.chain.CurrentBlock() + td = handler.chain.GetTd(head.Hash(), head.NumberU64()) + ) + time.Sleep(200 * time.Millisecond) + if err := remoteEth.Handshake(1, td, head.Hash(), genesis.Hash(), forkid.NewIDWithChain(handler.chain), forkid.NewFilter(handler.chain), nil); err != nil { + t.Fatalf("failed to run protocol handshake: %d", err) + } + // After the handshake completes, the source handler should stream the sink + // the votes, subscribe to all inbound network events + backend := new(testBscHandler) + bcasts := make(chan []*types.VoteEnvelope) + bcastSub := backend.voteBroadcasts.Subscribe(bcasts) + defer bcastSub.Unsubscribe() + + go bsc.Handle(backend, remoteBsc) + + // Make sure we get all the votes on the correct channels + seen := make(map[common.Hash]struct{}) + for len(seen) < len(insert) { + votes := <-bcasts + for _, vote := range votes { + if _, ok := seen[vote.Hash()]; ok { + t.Errorf("duplicate vote broadcast: %x", vote.Hash()) + } + seen[vote.Hash()] = struct{}{} + } + } + for _, vote := range insert { + if _, ok := seen[vote.Hash()]; !ok { + t.Errorf("missing vote: %x", vote.Hash()) + } + } + +} + +func TestRecvVotes67(t *testing.T) { testRecvVotes(t, eth.ETH67) } + +func testRecvVotes(t *testing.T, protocol uint) { + t.Parallel() + + // Create a message handler and fill the pool with big votes + handler := newTestHandler() + defer handler.close() + + protos := []p2p.Protocol{ + { + Name: "eth", + Version: eth.ETH66, + }, + { + Name: "eth", + Version: eth.ETH67, + }, + { + Name: "bsc", + Version: bsc.Bsc1, + }, + } + caps := []p2p.Cap{ + { + Name: "eth", + Version: eth.ETH66, + }, + { + Name: "eth", + Version: eth.ETH67, + }, + { + Name: "bsc", + Version: bsc.Bsc1, + }, + } + + // Create a source handler to send messages through and a sink peer to receive them + p2pEthSrc, p2pEthSink := p2p.MsgPipe() + defer p2pEthSrc.Close() + defer p2pEthSink.Close() + + localEth := eth.NewPeer(protocol, p2p.NewPeerWithProtocols(enode.ID{1}, protos, "", caps), p2pEthSrc, nil) + remoteEth := eth.NewPeer(protocol, p2p.NewPeerWithProtocols(enode.ID{2}, protos, "", caps), p2pEthSink, nil) + defer localEth.Close() + defer remoteEth.Close() + + p2pBscSrc, p2pBscSink := p2p.MsgPipe() + defer p2pBscSrc.Close() + defer p2pBscSink.Close() + + localBsc := bsc.NewPeer(bsc.Bsc1, p2p.NewPeerWithProtocols(enode.ID{1}, protos, "", caps), p2pBscSrc) + remoteBsc := bsc.NewPeer(bsc.Bsc1, p2p.NewPeerWithProtocols(enode.ID{3}, protos, "", caps), p2pBscSink) + defer localBsc.Close() + defer remoteBsc.Close() + + go func(p *bsc.Peer) { + (*bscHandler)(handler.handler).RunPeer(p, func(peer *bsc.Peer) error { + return bsc.Handle((*bscHandler)(handler.handler), peer) + }) + }(localBsc) + + time.Sleep(200 * time.Millisecond) + remoteBsc.Handshake() + + time.Sleep(200 * time.Millisecond) + go func(p *eth.Peer) { + handler.handler.runEthPeer(p, func(peer *eth.Peer) error { + return eth.Handle((*ethHandler)(handler.handler), peer) + }) + }(localEth) + + // Run the handshake locally to avoid spinning up a source handler + var ( + genesis = handler.chain.Genesis() + head = handler.chain.CurrentBlock() + td = handler.chain.GetTd(head.Hash(), head.NumberU64()) + ) + time.Sleep(200 * time.Millisecond) + if err := remoteEth.Handshake(1, td, head.Hash(), genesis.Hash(), forkid.NewIDWithChain(handler.chain), forkid.NewFilter(handler.chain), nil); err != nil { + t.Fatalf("failed to run protocol handshake: %d", err) + } + + votesCh := make(chan core.NewVoteEvent) + sub := handler.votepool.SubscribeNewVoteEvent(votesCh) + defer sub.Unsubscribe() + // Send the vote to the sink and verify that it's added to the vote pool + vote := types.VoteEnvelope{ + VoteAddress: types.BLSPublicKey{}, + Signature: types.BLSSignature{}, + Data: &types.VoteData{ + SourceNumber: uint64(0), + SourceHash: common.BytesToHash(common.Hex2Bytes(string(rune(0)))), + TargetNumber: uint64(1), + TargetHash: common.BytesToHash(common.Hex2Bytes(string(rune(1)))), + }, + } + + remoteBsc.AsyncSendVotes([]*types.VoteEnvelope{&vote}) + time.Sleep(100 * time.Millisecond) + select { + case event := <-votesCh: + if event.Vote.Hash() != vote.Hash() { + t.Errorf("added wrong vote hash: got %v, want %v", event.Vote.Hash(), vote.Hash()) + } + case <-time.After(2 * time.Second): + t.Errorf("no NewVotesEvent received within 2 seconds") + } +} diff --git a/eth/handler_diff_test.go b/eth/handler_diff_test.go index 0956459d98..06d16b4116 100644 --- a/eth/handler_diff_test.go +++ b/eth/handler_diff_test.go @@ -84,11 +84,13 @@ func newTestBackendWithGenerator(blocks int) *testBackend { panic(err) } txpool := newTestTxPool() + votepool := newTestVotePool() handler, _ := newHandler(&handlerConfig{ Database: db, Chain: chain, TxPool: txpool, + VotePool: votepool, Network: 1, Sync: downloader.FullSync, BloomCache: 1, diff --git a/eth/handler_eth.go b/eth/handler_eth.go index 8f01cf528c..f7e3fba880 100644 --- a/eth/handler_eth.go +++ b/eth/handler_eth.go @@ -76,6 +76,7 @@ func (h *ethHandler) Handle(peer *eth.Peer, packet eth.Packet) error { case *eth.PooledTransactionsPacket: return h.txFetcher.Enqueue(peer.ID(), *packet, true) + default: return fmt.Errorf("unexpected eth packet type: %T", packet) } diff --git a/eth/handler_eth_test.go b/eth/handler_eth_test.go index 74db6668c3..0144332e1c 100644 --- a/eth/handler_eth_test.go +++ b/eth/handler_eth_test.go @@ -33,6 +33,7 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/eth/downloader" + "github.com/ethereum/go-ethereum/eth/protocols/bsc" "github.com/ethereum/go-ethereum/eth/protocols/eth" "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/p2p" @@ -90,11 +91,25 @@ func testForkIDSplit(t *testing.T, protocol uint) { configNoFork = ¶ms.ChainConfig{HomesteadBlock: big.NewInt(1)} configProFork = ¶ms.ChainConfig{ - HomesteadBlock: big.NewInt(1), - EIP150Block: big.NewInt(2), - EIP155Block: big.NewInt(2), - EIP158Block: big.NewInt(2), - ByzantiumBlock: big.NewInt(3), + HomesteadBlock: big.NewInt(1), + EIP150Block: big.NewInt(2), + EIP155Block: big.NewInt(2), + EIP158Block: big.NewInt(2), + ByzantiumBlock: big.NewInt(3), + ConstantinopleBlock: big.NewInt(4), + PetersburgBlock: big.NewInt(4), + IstanbulBlock: big.NewInt(4), + MuirGlacierBlock: big.NewInt(4), + RamanujanBlock: big.NewInt(4), + NielsBlock: big.NewInt(4), + MirrorSyncBlock: big.NewInt(4), + BrunoBlock: big.NewInt(4), + EulerBlock: big.NewInt(5), + GibbsBlock: big.NewInt(5), + NanoBlock: big.NewInt(5), + MoranBlock: big.NewInt(5), + LubanBlock: big.NewInt(6), + PlatoBlock: big.NewInt(6), } dbNoFork = rawdb.NewMemoryDatabase() dbProFork = rawdb.NewMemoryDatabase() @@ -115,6 +130,7 @@ func testForkIDSplit(t *testing.T, protocol uint) { Database: dbNoFork, Chain: chainNoFork, TxPool: newTestTxPool(), + VotePool: newTestVotePool(), Merger: consensus.NewMerger(rawdb.NewMemoryDatabase()), Network: 1, Sync: downloader.FullSync, @@ -124,6 +140,7 @@ func testForkIDSplit(t *testing.T, protocol uint) { Database: dbProFork, Chain: chainProFork, TxPool: newTestTxPool(), + VotePool: newTestVotePool(), Merger: consensus.NewMerger(rawdb.NewMemoryDatabase()), Network: 1, Sync: downloader.FullSync, @@ -230,7 +247,7 @@ func testForkIDSplit(t *testing.T, protocol uint) { t.Fatalf("fork ID rejection didn't happen") } } - case <-time.After(250 * time.Millisecond): + case <-time.After(10000 * time.Millisecond): t.Fatalf("split peers not rejected") } } @@ -239,7 +256,63 @@ func testForkIDSplit(t *testing.T, protocol uint) { // Tests that received transactions are added to the local pool. func TestRecvTransactions66(t *testing.T) { testRecvTransactions(t, eth.ETH66) } -func TestWaitDiffExtensionTimout(t *testing.T) { +func testRecvTransactions(t *testing.T, protocol uint) { + t.Parallel() + + // Create a message handler, configure it to accept transactions and watch them + handler := newTestHandler() + defer handler.close() + + handler.handler.acceptTxs = 1 // mark synced to accept transactions + + txs := make(chan core.NewTxsEvent) + sub := handler.txpool.SubscribeNewTxsEvent(txs) + defer sub.Unsubscribe() + + // Create a source peer to send messages through and a sink handler to receive them + p2pSrc, p2pSink := p2p.MsgPipe() + defer p2pSrc.Close() + defer p2pSink.Close() + + src := eth.NewPeer(protocol, p2p.NewPeerPipe(enode.ID{1}, "", nil, p2pSrc), p2pSrc, handler.txpool) + sink := eth.NewPeer(protocol, p2p.NewPeerPipe(enode.ID{2}, "", nil, p2pSink), p2pSink, handler.txpool) + defer src.Close() + defer sink.Close() + + go handler.handler.runEthPeer(sink, func(peer *eth.Peer) error { + return eth.Handle((*ethHandler)(handler.handler), peer) + }) + // Run the handshake locally to avoid spinning up a source handler + var ( + genesis = handler.chain.Genesis() + head = handler.chain.CurrentBlock() + td = handler.chain.GetTd(head.Hash(), head.NumberU64()) + ) + if err := src.Handshake(1, td, head.Hash(), genesis.Hash(), forkid.NewIDWithChain(handler.chain), forkid.NewFilter(handler.chain), nil); err != nil { + t.Fatalf("failed to run protocol handshake") + } + // Send the transaction to the sink and verify that it's added to the tx pool + tx := types.NewTransaction(0, common.Address{}, big.NewInt(0), 100000, big.NewInt(0), nil) + tx, _ = types.SignTx(tx, types.HomesteadSigner{}, testKey) + + if err := src.SendTransactions([]*types.Transaction{tx}); err != nil { + t.Fatalf("failed to send transaction: %v", err) + } + select { + case event := <-txs: + if len(event.Txs) != 1 { + t.Errorf("wrong number of added transactions: got %d, want 1", len(event.Txs)) + } else if event.Txs[0].Hash() != tx.Hash() { + t.Errorf("added wrong tx hash: got %v, want %v", event.Txs[0].Hash(), tx.Hash()) + } + case <-time.After(2 * time.Second): + t.Errorf("no NewTxsEvent received within 2 seconds") + } +} + +func TestWaitDiffExtensionTimout67(t *testing.T) { testWaitDiffExtensionTimout(t, eth.ETH67) } + +func testWaitDiffExtensionTimout(t *testing.T, protocol uint) { t.Parallel() // Create a message handler, configure it to accept transactions and watch them @@ -257,7 +330,7 @@ func TestWaitDiffExtensionTimout(t *testing.T) { }, } - sink := eth.NewPeer(eth.ETH67, p2p.NewPeerWithProtocols(enode.ID{2}, protos, "", []p2p.Cap{ + sink := eth.NewPeer(protocol, p2p.NewPeerWithProtocols(enode.ID{2}, protos, "", []p2p.Cap{ { Name: "diff", Version: 1, @@ -274,7 +347,9 @@ func TestWaitDiffExtensionTimout(t *testing.T) { } } -func TestWaitSnapExtensionTimout(t *testing.T) { +func TestWaitSnapExtensionTimout67(t *testing.T) { testWaitSnapExtensionTimout(t, eth.ETH67) } + +func testWaitSnapExtensionTimout(t *testing.T, protocol uint) { t.Parallel() // Create a message handler, configure it to accept transactions and watch them @@ -292,7 +367,7 @@ func TestWaitSnapExtensionTimout(t *testing.T) { }, } - sink := eth.NewPeer(eth.ETH67, p2p.NewPeerWithProtocols(enode.ID{2}, protos, "", []p2p.Cap{ + sink := eth.NewPeer(protocol, p2p.NewPeerWithProtocols(enode.ID{2}, protos, "", []p2p.Cap{ { Name: "snap", Version: 1, @@ -309,57 +384,40 @@ func TestWaitSnapExtensionTimout(t *testing.T) { } } -func testRecvTransactions(t *testing.T, protocol uint) { +func TestWaitBscExtensionTimout67(t *testing.T) { testWaitBscExtensionTimout(t, eth.ETH67) } + +func testWaitBscExtensionTimout(t *testing.T, protocol uint) { t.Parallel() // Create a message handler, configure it to accept transactions and watch them handler := newTestHandler() defer handler.close() - handler.handler.acceptTxs = 1 // mark synced to accept transactions - - txs := make(chan core.NewTxsEvent) - sub := handler.txpool.SubscribeNewTxsEvent(txs) - defer sub.Unsubscribe() - // Create a source peer to send messages through and a sink handler to receive them - p2pSrc, p2pSink := p2p.MsgPipe() - defer p2pSrc.Close() + _, p2pSink := p2p.MsgPipe() defer p2pSink.Close() - src := eth.NewPeer(protocol, p2p.NewPeerPipe(enode.ID{1}, "", nil, p2pSrc), p2pSrc, handler.txpool) - sink := eth.NewPeer(protocol, p2p.NewPeerPipe(enode.ID{2}, "", nil, p2pSink), p2pSink, handler.txpool) - defer src.Close() + protos := []p2p.Protocol{ + { + Name: "bsc", + Version: bsc.Bsc1, + }, + } + + sink := eth.NewPeer(protocol, p2p.NewPeerWithProtocols(enode.ID{2}, protos, "", []p2p.Cap{ + { + Name: "bsc", + Version: bsc.Bsc1, + }, + }), p2pSink, nil) defer sink.Close() - go handler.handler.runEthPeer(sink, func(peer *eth.Peer) error { + err := handler.handler.runEthPeer(sink, func(peer *eth.Peer) error { return eth.Handle((*ethHandler)(handler.handler), peer) }) - // Run the handshake locally to avoid spinning up a source handler - var ( - genesis = handler.chain.Genesis() - head = handler.chain.CurrentBlock() - td = handler.chain.GetTd(head.Hash(), head.NumberU64()) - ) - if err := src.Handshake(1, td, head.Hash(), genesis.Hash(), forkid.NewIDWithChain(handler.chain), forkid.NewFilter(handler.chain), nil); err != nil { - t.Fatalf("failed to run protocol handshake") - } - // Send the transaction to the sink and verify that it's added to the tx pool - tx := types.NewTransaction(0, common.Address{}, big.NewInt(0), 100000, big.NewInt(0), nil) - tx, _ = types.SignTx(tx, types.HomesteadSigner{}, testKey) - if err := src.SendTransactions([]*types.Transaction{tx}); err != nil { - t.Fatalf("failed to send transaction: %v", err) - } - select { - case event := <-txs: - if len(event.Txs) != 1 { - t.Errorf("wrong number of added transactions: got %d, want 1", len(event.Txs)) - } else if event.Txs[0].Hash() != tx.Hash() { - t.Errorf("added wrong tx hash: got %v, want %v", event.Txs[0].Hash(), tx.Hash()) - } - case <-time.After(2 * time.Second): - t.Errorf("no NewTxsEvent received within 2 seconds") + if err == nil || err.Error() != "peer wait timeout" { + t.Fatalf("error should be `peer wait timeout`") } } diff --git a/eth/handler_test.go b/eth/handler_test.go index 4d4c11592c..b38248e47b 100644 --- a/eth/handler_test.go +++ b/eth/handler_test.go @@ -136,10 +136,11 @@ func (p *testTxPool) SubscribeReannoTxsEvent(ch chan<- core.ReannoTxsEvent) even // preinitialized with some sane testing defaults and the transaction pool mocked // out. type testHandler struct { - db ethdb.Database - chain *core.BlockChain - txpool *testTxPool - handler *handler + db ethdb.Database + chain *core.BlockChain + txpool *testTxPool + votepool *testVotePool + handler *handler } // newTestHandler creates a new handler for testing purposes with no blocks. @@ -164,12 +165,14 @@ func newTestHandlerWithBlocks(blocks int) *testHandler { panic(err) } txpool := newTestTxPool() + votepool := newTestVotePool() handler, _ := newHandler(&handlerConfig{ Database: db, Chain: chain, TxPool: txpool, Merger: consensus.NewMerger(rawdb.NewMemoryDatabase()), + VotePool: votepool, Network: 1, Sync: downloader.SnapSync, BloomCache: 1, @@ -177,10 +180,11 @@ func newTestHandlerWithBlocks(blocks int) *testHandler { handler.Start(1000) return &testHandler{ - db: db, - chain: chain, - txpool: txpool, - handler: handler, + db: db, + chain: chain, + txpool: txpool, + votepool: votepool, + handler: handler, } } @@ -189,3 +193,45 @@ func (b *testHandler) close() { b.handler.Stop() b.chain.Stop() } + +// newTestVotePool creates a mock vote pool. +type testVotePool struct { + pool map[common.Hash]*types.VoteEnvelope // Hash map of collected votes + + voteFeed event.Feed // Notification feed to allow waiting for inclusion + lock sync.RWMutex // Protects the vote pool +} + +// newTestVotePool creates a mock vote pool. +func newTestVotePool() *testVotePool { + return &testVotePool{ + pool: make(map[common.Hash]*types.VoteEnvelope), + } +} + +func (t *testVotePool) PutVote(vote *types.VoteEnvelope) { + t.lock.Lock() + defer t.lock.Unlock() + + t.pool[vote.Hash()] = vote + t.voteFeed.Send(core.NewVoteEvent{Vote: vote}) +} + +func (t *testVotePool) FetchVoteByBlockHash(blockHash common.Hash) []*types.VoteEnvelope { + panic("implement me") +} + +func (t *testVotePool) GetVotes() []*types.VoteEnvelope { + t.lock.RLock() + defer t.lock.RUnlock() + + votes := make([]*types.VoteEnvelope, 0, len(t.pool)) + for _, vote := range t.pool { + votes = append(votes, vote) + } + return votes +} + +func (t *testVotePool) SubscribeNewVoteEvent(ch chan<- core.NewVoteEvent) event.Subscription { + return t.voteFeed.Subscribe(ch) +} diff --git a/eth/peer.go b/eth/peer.go index 802d1e5aac..77a150434c 100644 --- a/eth/peer.go +++ b/eth/peer.go @@ -20,6 +20,7 @@ import ( "math/big" "time" + "github.com/ethereum/go-ethereum/eth/protocols/bsc" "github.com/ethereum/go-ethereum/eth/protocols/trust" "github.com/ethereum/go-ethereum/eth/protocols/diff" @@ -41,6 +42,7 @@ type ethPeer struct { snapExt *snapPeer // Satellite `snap` connection diffExt *diffPeer trustExt *trustPeer + bscExt *bscPeer // Satellite `bsc` connection syncDrop *time.Timer // Connection dropper if `eth` sync progress isn't validated in time snapWait chan struct{} // Notification channel for snap connections @@ -76,6 +78,12 @@ type trustPeerInfo struct { Version uint `json:"version"` // Trust protocol version negotiated } +// bscPeerInfo represents a short summary of the `bsc` sub-protocol metadata known +// about a connected peer. +type bscPeerInfo struct { + Version uint `json:"version"` // bsc protocol version negotiated +} + // snapPeer is a wrapper around snap.Peer to maintain a few extra metadata. type snapPeer struct { *snap.Peer @@ -91,6 +99,11 @@ type trustPeer struct { *trust.Peer } +// bscPeer is a wrapper around bsc.Peer to maintain a few extra metadata. +type bscPeer struct { + *bsc.Peer +} + // info gathers and returns some `diff` protocol metadata known about a peer. func (p *diffPeer) info() *diffPeerInfo { return &diffPeerInfo{ @@ -112,3 +125,10 @@ func (p *trustPeer) info() *trustPeerInfo { Version: p.Version(), } } + +// info gathers and returns some `bsc` protocol metadata known about a peer. +func (p *bscPeer) info() *bscPeerInfo { + return &bscPeerInfo{ + Version: p.Version(), + } +} diff --git a/eth/peerset.go b/eth/peerset.go index 6484dae8dd..5dfb73934a 100644 --- a/eth/peerset.go +++ b/eth/peerset.go @@ -25,6 +25,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/eth/downloader" + "github.com/ethereum/go-ethereum/eth/protocols/bsc" "github.com/ethereum/go-ethereum/eth/protocols/diff" "github.com/ethereum/go-ethereum/eth/protocols/eth" "github.com/ethereum/go-ethereum/eth/protocols/snap" @@ -59,12 +60,17 @@ var ( // errTrustWithoutEth is returned if a peer attempts to connect only on the // trust protocol without advertising the eth main protocol. errTrustWithoutEth = errors.New("peer connected on trust without compatible eth support") + + // errBscWithoutEth is returned if a peer attempts to connect only on the + // bsc protocol without advertising the eth main protocol. + errBscWithoutEth = errors.New("peer connected on bsc without compatible eth support") ) const ( // extensionWaitTimeout is the maximum allowed time for the extension wait to // complete before dropping the connection as malicious. extensionWaitTimeout = 10 * time.Second + tryWaitTimeout = 100 * time.Millisecond ) // peerSet represents the collection of active peers currently participating in @@ -82,6 +88,9 @@ type peerSet struct { trustWait map[string]chan *trust.Peer // Peers connected on `eth` waiting for their trust extension trustPend map[string]*trust.Peer // Peers connected on the `trust` protocol, but not yet on `eth` + bscWait map[string]chan *bsc.Peer // Peers connected on `eth` waiting for their bsc extension + bscPend map[string]*bsc.Peer // Peers connected on the `bsc` protocol, but not yet on `eth` + lock sync.RWMutex closed bool } @@ -96,6 +105,8 @@ func newPeerSet() *peerSet { diffPend: make(map[string]*diff.Peer), trustWait: make(map[string]chan *trust.Peer), trustPend: make(map[string]*trust.Peer), + bscWait: make(map[string]chan *bsc.Peer), + bscPend: make(map[string]*bsc.Peer), } } @@ -193,6 +204,36 @@ func (ps *peerSet) registerTrustExtension(peer *trust.Peer) error { return nil } +// registerBscExtension unblocks an already connected `eth` peer waiting for its +// `bsc` extension, or if no such peer exists, tracks the extension for the time +// being until the `eth` main protocol starts looking for it. +func (ps *peerSet) registerBscExtension(peer *bsc.Peer) error { + // Reject the peer if it advertises `bsc` without `eth` as `bsc` is only a + // satellite protocol meaningful with the chain selection of `eth` + if !peer.RunningCap(eth.ProtocolName, eth.ProtocolVersions) { + return errBscWithoutEth + } + // Ensure nobody can double connect + ps.lock.Lock() + defer ps.lock.Unlock() + + id := peer.ID() + if _, ok := ps.peers[id]; ok { + return errPeerAlreadyRegistered // avoid connections with the same id as existing ones + } + if _, ok := ps.bscPend[id]; ok { + return errPeerAlreadyRegistered // avoid connections with the same id as pending ones + } + // Inject the peer into an `eth` counterpart is available, otherwise save for later + if wait, ok := ps.bscWait[id]; ok { + delete(ps.bscWait, id) + wait <- peer + return nil + } + ps.bscPend[id] = peer + return nil +} + // waitExtensions blocks until all satellite protocols are connected and tracked // by the peerset. func (ps *peerSet) waitSnapExtension(peer *eth.Peer) (*snap.Peer, error) { @@ -326,6 +367,65 @@ func (ps *peerSet) waitTrustExtension(peer *eth.Peer) (*trust.Peer, error) { } } +// waitBscExtension blocks until all satellite protocols are connected and tracked +// by the peerset. +func (ps *peerSet) waitBscExtension(peer *eth.Peer) (*bsc.Peer, error) { + // If the peer does not support a compatible `bsc`, don't wait + if !peer.RunningCap(bsc.ProtocolName, bsc.ProtocolVersions) { + return nil, nil + } + // Ensure nobody can double connect + ps.lock.Lock() + + id := peer.ID() + if _, ok := ps.peers[id]; ok { + ps.lock.Unlock() + return nil, errPeerAlreadyRegistered // avoid connections with the same id as existing ones + } + if _, ok := ps.bscWait[id]; ok { + ps.lock.Unlock() + return nil, errPeerAlreadyRegistered // avoid connections with the same id as pending ones + } + // If `bsc` already connected, retrieve the peer from the pending set + if bsc, ok := ps.bscPend[id]; ok { + delete(ps.bscPend, id) + + ps.lock.Unlock() + return bsc, nil + } + // Otherwise wait for `bsc` to connect concurrently + wait := make(chan *bsc.Peer) + ps.bscWait[id] = wait + ps.lock.Unlock() + + select { + case peer := <-wait: + return peer, nil + + case <-time.After(extensionWaitTimeout): + // could be deadlock, so we use TryLock to avoid it. + if ps.lock.TryLock() { + delete(ps.bscWait, id) + ps.lock.Unlock() + return nil, errPeerWaitTimeout + } + // if TryLock failed, we wait for a while and try again. + for { + select { + case <-wait: + // discard the peer, even though the peer arrived. + return nil, errPeerWaitTimeout + case <-time.After(tryWaitTimeout): + if ps.lock.TryLock() { + delete(ps.bscWait, id) + ps.lock.Unlock() + return nil, errPeerWaitTimeout + } + } + } + } +} + func (ps *peerSet) GetDiffPeer(pid string) downloader.IDiffPeer { if p := ps.peer(pid); p != nil && p.diffExt != nil { return p.diffExt @@ -349,7 +449,7 @@ func (ps *peerSet) GetVerifyPeers() []core.VerifyPeer { // registerPeer injects a new `eth` peer into the working set, or returns an error // if the peer is already known. -func (ps *peerSet) registerPeer(peer *eth.Peer, ext *snap.Peer, diffExt *diff.Peer, trustExt *trust.Peer) error { +func (ps *peerSet) registerPeer(peer *eth.Peer, ext *snap.Peer, diffExt *diff.Peer, trustExt *trust.Peer, bscExt *bsc.Peer) error { // Start tracking the new peer ps.lock.Lock() defer ps.lock.Unlock() @@ -374,6 +474,9 @@ func (ps *peerSet) registerPeer(peer *eth.Peer, ext *snap.Peer, diffExt *diff.Pe if trustExt != nil { eth.trustExt = &trustPeer{trustExt} } + if bscExt != nil { + eth.bscExt = &bscPeer{bscExt} + } ps.peers[id] = eth return nil } @@ -420,7 +523,7 @@ func (ps *peerSet) headPeers(num uint) []*ethPeer { } // peersWithoutBlock retrieves a list of peers that do not have a given block in -// their set of known hashes so it might be propagated to them. +// their set of known hashes, so it might be propagated to them. func (ps *peerSet) peersWithoutBlock(hash common.Hash) []*ethPeer { ps.lock.RLock() defer ps.lock.RUnlock() @@ -449,6 +552,21 @@ func (ps *peerSet) peersWithoutTransaction(hash common.Hash) []*ethPeer { return list } +// peersWithoutVote retrieves a list of peers that do not have a given +// vote in their set of known hashes. +func (ps *peerSet) peersWithoutVote(hash common.Hash) []*ethPeer { + ps.lock.RLock() + defer ps.lock.RUnlock() + + list := make([]*ethPeer, 0, len(ps.peers)) + for _, p := range ps.peers { + if p.bscExt != nil && !p.bscExt.KnownVote(hash) { + list = append(list, p) + } + } + return list +} + // len returns if the current number of `eth` peers in the set. Since the `snap` // peers are tied to the existence of an `eth` connection, that will always be a // subset of `eth`. diff --git a/eth/protocols/bsc/discovery.go b/eth/protocols/bsc/discovery.go new file mode 100644 index 0000000000..6a4fac346e --- /dev/null +++ b/eth/protocols/bsc/discovery.go @@ -0,0 +1,16 @@ +package bsc + +import ( + "github.com/ethereum/go-ethereum/rlp" +) + +// enrEntry is the ENR entry which advertises `bsc` protocol on the discovery. +type enrEntry struct { + // Ignore additional fields (for forward compatibility). + Rest []rlp.RawValue `rlp:"tail"` +} + +// ENRKey implements enr.Entry. +func (e enrEntry) ENRKey() string { + return "bsc" +} diff --git a/eth/protocols/bsc/handler.go b/eth/protocols/bsc/handler.go new file mode 100644 index 0000000000..e993f255f3 --- /dev/null +++ b/eth/protocols/bsc/handler.go @@ -0,0 +1,145 @@ +package bsc + +import ( + "fmt" + "time" + + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/metrics" + "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/p2p/enode" + "github.com/ethereum/go-ethereum/p2p/enr" +) + +// Handler is a callback to invoke from an outside runner after the boilerplate +// exchanges have passed. +type Handler func(peer *Peer) error + +type Backend interface { + // Chain retrieves the blockchain object to serve data. + Chain() *core.BlockChain + + // RunPeer is invoked when a peer joins on the `bsc` protocol. The handler + // should do any peer maintenance work, handshakes and validations. If all + // is passed, control should be given back to the `handler` to process the + // inbound messages going forward. + RunPeer(peer *Peer, handler Handler) error + + // PeerInfo retrieves all known `bsc` information about a peer. + PeerInfo(id enode.ID) interface{} + + // Handle is a callback to be invoked when a data packet is received from + // the remote peer. Only packets not consumed by the protocol handler will + // be forwarded to the backend. + Handle(peer *Peer, packet Packet) error +} + +// MakeProtocols constructs the P2P protocol definitions for `bsc`. +func MakeProtocols(backend Backend, dnsdisc enode.Iterator) []p2p.Protocol { + // Filter the discovery iterator for nodes advertising vote support. + dnsdisc = enode.Filter(dnsdisc, func(n *enode.Node) bool { + var vote enrEntry + return n.Load(&vote) == nil + }) + + protocols := make([]p2p.Protocol, len(ProtocolVersions)) + for i, version := range ProtocolVersions { + version := version // Closure + + protocols[i] = p2p.Protocol{ + Name: ProtocolName, + Version: version, + Length: protocolLengths[version], + Run: func(p *p2p.Peer, rw p2p.MsgReadWriter) error { + peer := NewPeer(version, p, rw) + defer peer.Close() + + return backend.RunPeer(peer, func(peer *Peer) error { + return Handle(backend, peer) + }) + }, + NodeInfo: func() interface{} { + return nodeInfo(backend.Chain()) + }, + PeerInfo: func(id enode.ID) interface{} { + return backend.PeerInfo(id) + }, + Attributes: []enr.Entry{&enrEntry{}}, + DialCandidates: dnsdisc, + } + } + return protocols +} + +// Handle is the callback invoked to manage the life cycle of a `bsc` peer. +// When this function terminates, the peer is disconnected. +func Handle(backend Backend, peer *Peer) error { + for { + if err := handleMessage(backend, peer); err != nil { + peer.Log().Debug("Message handling failed in `bsc`", "err", err) + return err + } + } +} + +type msgHandler func(backend Backend, msg Decoder, peer *Peer) error +type Decoder interface { + Decode(val interface{}) error +} + +var bsc1 = map[uint64]msgHandler{ + VotesMsg: handleVotes, +} + +// handleMessage is invoked whenever an inbound message is received from a +// remote peer on the `bsc` protocol. The remote connection is torn down upon +// returning any error. +func handleMessage(backend Backend, peer *Peer) error { + // Read the next message from the remote peer, and ensure it's fully consumed + msg, err := peer.rw.ReadMsg() + if err != nil { + return err + } + if msg.Size > maxMessageSize { + return fmt.Errorf("%w: %v > %v", errMsgTooLarge, msg.Size, maxMessageSize) + } + defer msg.Discard() + + var handlers = bsc1 + + // Track the amount of time it takes to serve the request and run the handler + if metrics.Enabled { + h := fmt.Sprintf("%s/%s/%d/%#02x", p2p.HandleHistName, ProtocolName, peer.Version(), msg.Code) + defer func(start time.Time) { + sampler := func() metrics.Sample { + return metrics.ResettingSample( + metrics.NewExpDecaySample(1028, 0.015), + ) + } + metrics.GetOrRegisterHistogramLazy(h, nil, sampler).Update(time.Since(start).Microseconds()) + }(time.Now()) + } + if handler := handlers[msg.Code]; handler != nil { + return handler(backend, msg, peer) + } + return fmt.Errorf("%w: %v", errInvalidMsgCode, msg.Code) +} + +func handleVotes(backend Backend, msg Decoder, peer *Peer) error { + ann := new(VotesPacket) + if err := msg.Decode(ann); err != nil { + return fmt.Errorf("%w: message %v: %v", errDecode, msg, err) + } + // Schedule all the unknown hashes for retrieval + peer.markVotes(ann.Votes) + return backend.Handle(peer, ann) +} + +// NodeInfo represents a short summary of the `bsc` sub-protocol metadata +// known about the host peer. +type NodeInfo struct{} + +// nodeInfo retrieves some `bsc` protocol metadata about the running host node. +func nodeInfo(_ *core.BlockChain) *NodeInfo { + return &NodeInfo{} +} diff --git a/eth/protocols/bsc/handshake.go b/eth/protocols/bsc/handshake.go new file mode 100644 index 0000000000..c8e74f3d12 --- /dev/null +++ b/eth/protocols/bsc/handshake.go @@ -0,0 +1,68 @@ +package bsc + +import ( + "fmt" + "time" + + "github.com/ethereum/go-ethereum/common/gopool" + "github.com/ethereum/go-ethereum/p2p" +) + +const ( + // handshakeTimeout is the maximum allowed time for the `bsc` handshake to + // complete before dropping the connection as malicious. + handshakeTimeout = 5 * time.Second +) + +// Handshake executes the bsc protocol handshake, +func (p *Peer) Handshake() error { + // Send out own handshake in a new thread + errc := make(chan error, 2) + + var cap BscCapPacket // safe to read after two values have been received from errc + + gopool.Submit(func() { + errc <- p2p.Send(p.rw, BscCapMsg, &BscCapPacket{ + ProtocolVersion: p.version, + Extra: defaultExtra, + }) + }) + gopool.Submit(func() { + errc <- p.readCap(&cap) + }) + timeout := time.NewTimer(handshakeTimeout) + defer timeout.Stop() + for i := 0; i < 2; i++ { + select { + case err := <-errc: + if err != nil { + return err + } + case <-timeout.C: + return p2p.DiscReadTimeout + } + } + return nil +} + +// readCap reads the remote handshake message. +func (p *Peer) readCap(cap *BscCapPacket) error { + msg, err := p.rw.ReadMsg() + if err != nil { + return err + } + if msg.Code != BscCapMsg { + return fmt.Errorf("%w: first msg has code %x (!= %x)", errNoBscCapMsg, msg.Code, BscCapMsg) + } + if msg.Size > maxMessageSize { + return fmt.Errorf("%w: %v > %v", errMsgTooLarge, msg.Size, maxMessageSize) + } + // Decode the handshake and make sure everything matches + if err := msg.Decode(cap); err != nil { + return fmt.Errorf("%w: message %v: %v", errDecode, msg, err) + } + if cap.ProtocolVersion != p.version { + return fmt.Errorf("%w: %d (!= %d)", errProtocolVersionMismatch, cap.ProtocolVersion, p.version) + } + return nil +} diff --git a/eth/protocols/bsc/peer.go b/eth/protocols/bsc/peer.go new file mode 100644 index 0000000000..e66ab2a6b3 --- /dev/null +++ b/eth/protocols/bsc/peer.go @@ -0,0 +1,157 @@ +package bsc + +import ( + mapset "github.com/deckarep/golang-set" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/p2p" +) + +const ( + // maxKnownVotes is the maximum vote hashes to keep in the known list + // before starting to randomly evict them. + maxKnownVotes = 5376 +) + +// max is a helper function which returns the larger of the two given integers. +func max(a, b int) int { + if a > b { + return a + } + return b +} + +// Peer is a collection of relevant information we have about a `bsc` peer. +type Peer struct { + id string // Unique ID for the peer, cached + knownVotes *knownCache // Set of vote hashes known to be known by this peer + voteBroadcast chan []*types.VoteEnvelope // Channel used to queue votes propagation requests + + *p2p.Peer // The embedded P2P package peer + rw p2p.MsgReadWriter // Input/output streams for bsc + version uint // Protocol version negotiated + logger log.Logger // Contextual logger with the peer id injected + term chan struct{} // Termination channel to stop the broadcasters +} + +// NewPeer create a wrapper for a network connection and negotiated protocol +// version. +func NewPeer(version uint, p *p2p.Peer, rw p2p.MsgReadWriter) *Peer { + id := p.ID().String() + peer := &Peer{ + id: id, + knownVotes: newKnownCache(maxKnownVotes), + voteBroadcast: make(chan []*types.VoteEnvelope), + Peer: p, + rw: rw, + version: version, + logger: log.New("peer", id[:8]), + term: make(chan struct{}), + } + go peer.broadcastVotes() + return peer +} + +// ID retrieves the peer's unique identifier. +func (p *Peer) ID() string { + return p.id +} + +// Version retrieves the peer's negotiated `bsc` protocol version. +func (p *Peer) Version() uint { + return p.version +} + +// Log overrides the P2P logget with the higher level one containing only the id. +func (p *Peer) Log() log.Logger { + return p.logger +} + +// Close signals the broadcast goroutine to terminate. Only ever call this if +// you created the peer yourself via NewPeer. Otherwise let whoever created it +// clean it up! +func (p *Peer) Close() { + close(p.term) +} + +// KnownVote returns whether peer is known to already have a vote. +func (p *Peer) KnownVote(hash common.Hash) bool { + return p.knownVotes.contains(hash) +} + +// markVotes marks votes as known for the peer, ensuring that they +// will never be repropagated to this particular peer. +func (p *Peer) markVotes(votes []*types.VoteEnvelope) { + for _, vote := range votes { + if !p.knownVotes.contains(vote.Hash()) { + // If we reached the memory allowance, drop a previously known vote hash + p.knownVotes.add(vote.Hash()) + } + } +} + +// sendVotes propagates a batch of votes to the remote peer. +func (p *Peer) sendVotes(votes []*types.VoteEnvelope) error { + // Mark all the votes as known, but ensure we don't overflow our limits + p.markVotes(votes) + return p2p.Send(p.rw, VotesMsg, &VotesPacket{votes}) +} + +// AsyncSendVotes queues a batch of vote hashes for propagation to a remote peer. If +// the peer's broadcast queue is full, the event is silently dropped. +func (p *Peer) AsyncSendVotes(votes []*types.VoteEnvelope) { + select { + case p.voteBroadcast <- votes: + case <-p.term: + p.Log().Debug("Dropping vote propagation", "count", len(votes)) + } +} + +// broadcastVotes is a write loop that schedules votes broadcasts +// to the remote peer. The goal is to have an async writer that does not lock up +// node internals and at the same time rate limits queued data. +func (p *Peer) broadcastVotes() { + for { + select { + case votes := <-p.voteBroadcast: + if err := p.sendVotes(votes); err != nil { + return + } + p.Log().Trace("Sent votes", "count", len(votes)) + + case <-p.term: + return + } + } +} + +// knownCache is a cache for known hashes. +type knownCache struct { + hashes mapset.Set + max int +} + +// newKnownCache creates a new knownCache with a max capacity. +func newKnownCache(max int) *knownCache { + return &knownCache{ + max: max, + hashes: mapset.NewSet(), + } +} + +// add adds a list of elements to the set. +func (k *knownCache) add(hashes ...common.Hash) { + for k.hashes.Cardinality() > max(0, k.max-len(hashes)) { + k.hashes.Pop() + } + for _, hash := range hashes { + k.hashes.Add(hash) + } +} + +// contains returns whether the given item is in the set. +func (k *knownCache) contains(hash common.Hash) bool { + return k.hashes.Contains(hash) +} diff --git a/eth/protocols/bsc/protocol.go b/eth/protocols/bsc/protocol.go new file mode 100644 index 0000000000..a063531f07 --- /dev/null +++ b/eth/protocols/bsc/protocol.go @@ -0,0 +1,66 @@ +package bsc + +import ( + "errors" + + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/rlp" +) + +// Constants to match up protocol versions and messages +const ( + Bsc1 = 1 +) + +// ProtocolName is the official short name of the `bsc` protocol used during +// devp2p capability negotiation. +const ProtocolName = "bsc" + +// ProtocolVersions are the supported versions of the `bsc` protocol (first +// is primary). +var ProtocolVersions = []uint{Bsc1} + +// protocolLengths are the number of implemented message corresponding to +// different protocol versions. +var protocolLengths = map[uint]uint64{Bsc1: 2} + +// maxMessageSize is the maximum cap on the size of a protocol message. +const maxMessageSize = 10 * 1024 * 1024 + +const ( + BscCapMsg = 0x00 // bsc capability msg used upon handshake + VotesMsg = 0x01 +) + +var defaultExtra = []byte{0x00} + +var ( + errNoBscCapMsg = errors.New("no bsc capability message") + errMsgTooLarge = errors.New("message too long") + errDecode = errors.New("invalid message") + errInvalidMsgCode = errors.New("invalid message code") + errProtocolVersionMismatch = errors.New("protocol version mismatch") +) + +// Packet represents a p2p message in the `bsc` protocol. +type Packet interface { + Name() string // Name returns a string corresponding to the message type. + Kind() byte // Kind returns the message type. +} + +// BscCapPacket is the network packet for bsc capability message. +type BscCapPacket struct { + ProtocolVersion uint + Extra rlp.RawValue // for extension +} + +// VotesPacket is the network packet for votes record. +type VotesPacket struct { + Votes []*types.VoteEnvelope +} + +func (*BscCapPacket) Name() string { return "BscCap" } +func (*BscCapPacket) Kind() byte { return BscCapMsg } + +func (*VotesPacket) Name() string { return "Votes" } +func (*VotesPacket) Kind() byte { return VotesMsg } diff --git a/eth/protocols/bsc/protocol_test.go b/eth/protocols/bsc/protocol_test.go new file mode 100644 index 0000000000..8597021411 --- /dev/null +++ b/eth/protocols/bsc/protocol_test.go @@ -0,0 +1,132 @@ +package bsc + +import ( + "bytes" + "encoding/hex" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/rlp" +) + +// TestBsc1Messages tests the encoding of defined Bsc1 messages +func TestBsc1Messages(t *testing.T) { + var ( + BLSPublicKey = "b32d4d46a7127dcc865f0d30f2ee3dcd5983b686f4e3a9202afc8b608652001c9938906ae1ff1417486096e32511f1bc" + voteDataSet = []types.VoteData{ + { + SourceNumber: 0, + SourceHash: common.HexToHash("0x6d3c66c5357ec91d5c43af47e234a939b22557cbb552dc45bebbceeed90fbe34"), + TargetNumber: 1, + TargetHash: common.HexToHash("0xd0bc67b50915467ada963c35ee00950f664788e47da8139d8c178653171034f1"), + }, + { + SourceNumber: 0, + SourceHash: common.HexToHash("0x6d3c66c5357ec91d5c43af47e234a939b22557cbb552dc45bebbceeed90fbe34"), + TargetNumber: 2, + TargetHash: common.HexToHash("0xc2d18d5a59d65da573f70c4d30448482418894e018b0d189db24ea4fd02d7aa1"), + }, + { + SourceNumber: 0, + SourceHash: common.HexToHash("0x6d3c66c5357ec91d5c43af47e234a939b22557cbb552dc45bebbceeed90fbe34"), + TargetNumber: 4, + TargetHash: common.HexToHash("0xbd1bdaf8a8f5c00c464df2856a9e2ef23b8dcc906e6490d3cd295ebb5eb124c3"), + }, + { + SourceNumber: 0, + SourceHash: common.HexToHash("0x6d3c66c5357ec91d5c43af47e234a939b22557cbb552dc45bebbceeed90fbe34"), + TargetNumber: 8, + TargetHash: common.HexToHash("0x3073782ecabb5ef0673e95962273482347a2c7b30a0a7124c664443d0a43f1e1"), + }, + { + SourceNumber: 0, + SourceHash: common.HexToHash("0x6d3c66c5357ec91d5c43af47e234a939b22557cbb552dc45bebbceeed90fbe34"), + TargetNumber: 16, + TargetHash: common.HexToHash("0xc119833266327fd7e0cd929c6a847ae7d1689df5066dfdde2e52f51c0ecbcc3f"), + }, + { + SourceNumber: 0, + SourceHash: common.HexToHash("0x6d3c66c5357ec91d5c43af47e234a939b22557cbb552dc45bebbceeed90fbe34"), + TargetNumber: 32, + TargetHash: common.HexToHash("0x3b5650bcb98381e463871a15a3f601cdc26843d76f4d3461333d7feae38a1786"), + }, + { + SourceNumber: 0, + SourceHash: common.HexToHash("0x6d3c66c5357ec91d5c43af47e234a939b22557cbb552dc45bebbceeed90fbe34"), + TargetNumber: 64, + TargetHash: common.HexToHash("0x5e38b4d98904178d60d58f5bc1687b0c7df114a51f2007d3ee3e6e732539f130"), + }, + { + SourceNumber: 0, + SourceHash: common.HexToHash("0x6d3c66c5357ec91d5c43af47e234a939b22557cbb552dc45bebbceeed90fbe34"), + TargetNumber: 128, + TargetHash: common.HexToHash("0xa4a64a7d511d3ff6982b5a79e9a485508477b98996c570a220f9daea0c7682f8"), + }, + { + SourceNumber: 0, + SourceHash: common.HexToHash("0x6d3c66c5357ec91d5c43af47e234a939b22557cbb552dc45bebbceeed90fbe34"), + TargetNumber: 256, + TargetHash: common.HexToHash("0xd313672c2653fc13e75a9dafdcee93f444caf2cffb04585d3e306fd15418b7e2"), + }, + { + SourceNumber: 0, + SourceHash: common.HexToHash("0x6d3c66c5357ec91d5c43af47e234a939b22557cbb552dc45bebbceeed90fbe34"), + TargetNumber: 512, + TargetHash: common.HexToHash("0x3c5fe2e5439ca7a7f1a3de7d5c0914c37261451c87654397dd45f207109839ae"), + }, + { + SourceNumber: 0, + SourceHash: common.HexToHash("0x6d3c66c5357ec91d5c43af47e234a939b22557cbb552dc45bebbceeed90fbe34"), + TargetNumber: 1024, + TargetHash: common.HexToHash("0x088eeeb07acff0db3ae2585195e9fd23bdf54b55077cab87d1632b08dd2c043b"), + }, + } + signatures = []string{ + "91f8a39f99a0b3632d248e635ab0e7b5ff68071fa4def5c2df9f249db7d393c0ba89eb28a65f2a6ba836baddb961b9c312c70a87d130edf944b340649218335c91078cce808da75ff69f673bab3ecdf068c33b1ab147c54298056b19e9cc625d", + "a56cd257f9a4b4830c9bfadaa751c7b1d4e9c6899127c145987a55a7cfa0d1b7d114cb2523ea4e2efee0326cfc5a1cd912eaf7f0c4c0be3193677284533f1709fbd75471a9fb22aea358cdbf2e900628d7c504ce7245e8af6fdd1039dfa3c0bd", + "893f8aff7fc523a7aff006aaba71fbde5f1eee1f4683d405892ffb9ab9282a5dae01054210ff6873ee76f86b9afdef2e128932b26696e3f7e1de7fe7d3fdd1c41273912ff5d1002cba176dbf84e1fe2edb60b114129b89e1329a03f7d9843d04", + "b3585bf55f1e0d8bc0f544a386e6fc4ec37de52330f69b450f579050acda6279a8a38172ed2f01dfdb57cf7dd2a314970aa8a3168234cbd29adfc6a0efd080f57d7e195dafbf5b6db087e8b943aa634f797f8f6d4e5bf04681d7ce2218e59465", + "9366e823b456049cd10ed1aa8f02a58ce2fa4caea7e8c776d6aec9c42f4263b40b0f2d76cc55a598b378381f32ef33520d47e28707027c25e38eb971cddb379e0ded5e814ce70108d65855084a11484fd08447520b7ce79ac1e680020b243747", + "aafd383c9537d750358ea077d45476cf6c1541e717c690ebe5dc5442c2af732fba17b45c60b2c49de94f5121f318b6ae021c56ae06588c6552f1d5b87a166cb8050f287b528b20556033603f6a6649ccec4792c86ae5f6353cf6b7527ac40127", + "90d9dc467a64fe7852b2e0117806409a8f12a036849d69396282088f8d86adb3adcd46b1fde51b4630a6b64c2f8652f30a46609c49b33f50c9f4641e30900ee420f9b81b2ad59a2376dcf4e065ecf832fbf738ad5b73becd2f7add27e6c14d5f", + "8f7d6bc28626dc143208aaa7b97146510f01b1a108dead65f8fddf0ec07835bca91081f9e759656d52dd7d4adaac14220c8c62aa1dd09151fe8000ce4347b100ac496593058ae11b40c74b3049d38076d07301c9dc9586baf93d9c81b4e5d424", + "b6c17077217baa5930fb04e14b6ba7203b3c854e8f1363b48ad753d96db1b4ffed36d60d8b67e86f7f76504f0abefff80ed1e4f11ff192dbfc26a0f059f7b9f66f9e883fef208cc3f58c7ce49d8e854cf8a0e48c59c7407ebfe946cfd62bf3be", + "979b1d101e51731749c72fb160dd1245d69ebd6ca81c0519464d3bca9ec3db493cf4b45ebbb7f60fbd12f0705bd788000558bdedc335cedac2100169965b2794fae8a386b2e9ece86ea6952fadeb8501d9aad00e091713cc06d30c5885c3ecf0", + "8d035b04d8ef6c13117acc1ed9d0586a141f123494f21eeaaead5dd9f623933541b293eef403d2f3e8ede84f9dfe3dc10cbd3fa6bdf3e977dcf2d18a4dca84f8bd9b24fca8e7de4180b9aa6208ad6e756b1c81e98afc8e6994824b5c076857f8", + } + + votesSet []*types.VoteEnvelope + ) + + // Init the vote data, taken from a local node + pubKeyBytes, _ := hex.DecodeString(BLSPublicKey) + { + for i, voteData := range voteDataSet { + vote := new(types.VoteEnvelope) + voteAddress := new(types.BLSPublicKey) + signature := new(types.BLSSignature) + sigBytes, _ := hex.DecodeString(signatures[i]) + copy(voteAddress[:], pubKeyBytes) + copy(signature[:], sigBytes) + vote.VoteAddress = *voteAddress + vote.Signature = *signature + vote.Data = &voteData + votesSet = append(votesSet, vote) + } + } + + for i, tc := range []struct { + message interface{} + want []byte + }{ + { + VotesPacket{votesSet}, + common.FromHex("f90982f9097ff8dbb0b32d4d46a7127dcc865f0d30f2ee3dcd5983b686f4e3a9202afc8b608652001c9938906ae1ff1417486096e32511f1bcb86091f8a39f99a0b3632d248e635ab0e7b5ff68071fa4def5c2df9f249db7d393c0ba89eb28a65f2a6ba836baddb961b9c312c70a87d130edf944b340649218335c91078cce808da75ff69f673bab3ecdf068c33b1ab147c54298056b19e9cc625df84680a06d3c66c5357ec91d5c43af47e234a939b22557cbb552dc45bebbceeed90fbe34820400a0088eeeb07acff0db3ae2585195e9fd23bdf54b55077cab87d1632b08dd2c043bf8dbb0b32d4d46a7127dcc865f0d30f2ee3dcd5983b686f4e3a9202afc8b608652001c9938906ae1ff1417486096e32511f1bcb860a56cd257f9a4b4830c9bfadaa751c7b1d4e9c6899127c145987a55a7cfa0d1b7d114cb2523ea4e2efee0326cfc5a1cd912eaf7f0c4c0be3193677284533f1709fbd75471a9fb22aea358cdbf2e900628d7c504ce7245e8af6fdd1039dfa3c0bdf84680a06d3c66c5357ec91d5c43af47e234a939b22557cbb552dc45bebbceeed90fbe34820400a0088eeeb07acff0db3ae2585195e9fd23bdf54b55077cab87d1632b08dd2c043bf8dbb0b32d4d46a7127dcc865f0d30f2ee3dcd5983b686f4e3a9202afc8b608652001c9938906ae1ff1417486096e32511f1bcb860893f8aff7fc523a7aff006aaba71fbde5f1eee1f4683d405892ffb9ab9282a5dae01054210ff6873ee76f86b9afdef2e128932b26696e3f7e1de7fe7d3fdd1c41273912ff5d1002cba176dbf84e1fe2edb60b114129b89e1329a03f7d9843d04f84680a06d3c66c5357ec91d5c43af47e234a939b22557cbb552dc45bebbceeed90fbe34820400a0088eeeb07acff0db3ae2585195e9fd23bdf54b55077cab87d1632b08dd2c043bf8dbb0b32d4d46a7127dcc865f0d30f2ee3dcd5983b686f4e3a9202afc8b608652001c9938906ae1ff1417486096e32511f1bcb860b3585bf55f1e0d8bc0f544a386e6fc4ec37de52330f69b450f579050acda6279a8a38172ed2f01dfdb57cf7dd2a314970aa8a3168234cbd29adfc6a0efd080f57d7e195dafbf5b6db087e8b943aa634f797f8f6d4e5bf04681d7ce2218e59465f84680a06d3c66c5357ec91d5c43af47e234a939b22557cbb552dc45bebbceeed90fbe34820400a0088eeeb07acff0db3ae2585195e9fd23bdf54b55077cab87d1632b08dd2c043bf8dbb0b32d4d46a7127dcc865f0d30f2ee3dcd5983b686f4e3a9202afc8b608652001c9938906ae1ff1417486096e32511f1bcb8609366e823b456049cd10ed1aa8f02a58ce2fa4caea7e8c776d6aec9c42f4263b40b0f2d76cc55a598b378381f32ef33520d47e28707027c25e38eb971cddb379e0ded5e814ce70108d65855084a11484fd08447520b7ce79ac1e680020b243747f84680a06d3c66c5357ec91d5c43af47e234a939b22557cbb552dc45bebbceeed90fbe34820400a0088eeeb07acff0db3ae2585195e9fd23bdf54b55077cab87d1632b08dd2c043bf8dbb0b32d4d46a7127dcc865f0d30f2ee3dcd5983b686f4e3a9202afc8b608652001c9938906ae1ff1417486096e32511f1bcb860aafd383c9537d750358ea077d45476cf6c1541e717c690ebe5dc5442c2af732fba17b45c60b2c49de94f5121f318b6ae021c56ae06588c6552f1d5b87a166cb8050f287b528b20556033603f6a6649ccec4792c86ae5f6353cf6b7527ac40127f84680a06d3c66c5357ec91d5c43af47e234a939b22557cbb552dc45bebbceeed90fbe34820400a0088eeeb07acff0db3ae2585195e9fd23bdf54b55077cab87d1632b08dd2c043bf8dbb0b32d4d46a7127dcc865f0d30f2ee3dcd5983b686f4e3a9202afc8b608652001c9938906ae1ff1417486096e32511f1bcb86090d9dc467a64fe7852b2e0117806409a8f12a036849d69396282088f8d86adb3adcd46b1fde51b4630a6b64c2f8652f30a46609c49b33f50c9f4641e30900ee420f9b81b2ad59a2376dcf4e065ecf832fbf738ad5b73becd2f7add27e6c14d5ff84680a06d3c66c5357ec91d5c43af47e234a939b22557cbb552dc45bebbceeed90fbe34820400a0088eeeb07acff0db3ae2585195e9fd23bdf54b55077cab87d1632b08dd2c043bf8dbb0b32d4d46a7127dcc865f0d30f2ee3dcd5983b686f4e3a9202afc8b608652001c9938906ae1ff1417486096e32511f1bcb8608f7d6bc28626dc143208aaa7b97146510f01b1a108dead65f8fddf0ec07835bca91081f9e759656d52dd7d4adaac14220c8c62aa1dd09151fe8000ce4347b100ac496593058ae11b40c74b3049d38076d07301c9dc9586baf93d9c81b4e5d424f84680a06d3c66c5357ec91d5c43af47e234a939b22557cbb552dc45bebbceeed90fbe34820400a0088eeeb07acff0db3ae2585195e9fd23bdf54b55077cab87d1632b08dd2c043bf8dbb0b32d4d46a7127dcc865f0d30f2ee3dcd5983b686f4e3a9202afc8b608652001c9938906ae1ff1417486096e32511f1bcb860b6c17077217baa5930fb04e14b6ba7203b3c854e8f1363b48ad753d96db1b4ffed36d60d8b67e86f7f76504f0abefff80ed1e4f11ff192dbfc26a0f059f7b9f66f9e883fef208cc3f58c7ce49d8e854cf8a0e48c59c7407ebfe946cfd62bf3bef84680a06d3c66c5357ec91d5c43af47e234a939b22557cbb552dc45bebbceeed90fbe34820400a0088eeeb07acff0db3ae2585195e9fd23bdf54b55077cab87d1632b08dd2c043bf8dbb0b32d4d46a7127dcc865f0d30f2ee3dcd5983b686f4e3a9202afc8b608652001c9938906ae1ff1417486096e32511f1bcb860979b1d101e51731749c72fb160dd1245d69ebd6ca81c0519464d3bca9ec3db493cf4b45ebbb7f60fbd12f0705bd788000558bdedc335cedac2100169965b2794fae8a386b2e9ece86ea6952fadeb8501d9aad00e091713cc06d30c5885c3ecf0f84680a06d3c66c5357ec91d5c43af47e234a939b22557cbb552dc45bebbceeed90fbe34820400a0088eeeb07acff0db3ae2585195e9fd23bdf54b55077cab87d1632b08dd2c043bf8dbb0b32d4d46a7127dcc865f0d30f2ee3dcd5983b686f4e3a9202afc8b608652001c9938906ae1ff1417486096e32511f1bcb8608d035b04d8ef6c13117acc1ed9d0586a141f123494f21eeaaead5dd9f623933541b293eef403d2f3e8ede84f9dfe3dc10cbd3fa6bdf3e977dcf2d18a4dca84f8bd9b24fca8e7de4180b9aa6208ad6e756b1c81e98afc8e6994824b5c076857f8f84680a06d3c66c5357ec91d5c43af47e234a939b22557cbb552dc45bebbceeed90fbe34820400a0088eeeb07acff0db3ae2585195e9fd23bdf54b55077cab87d1632b08dd2c043b"), + }, + } { + if have, _ := rlp.EncodeToBytes(tc.message); !bytes.Equal(have, tc.want) { + t.Errorf("test %d, type %T, have\n\t%x\nwant\n\t%x", i, tc.message, have, tc.want) + } + } +} diff --git a/eth/protocols/diff/handler.go b/eth/protocols/diff/handler.go index 18ec4e2541..4bbf24f6fe 100644 --- a/eth/protocols/diff/handler.go +++ b/eth/protocols/diff/handler.go @@ -101,7 +101,7 @@ func handleMessage(backend Backend, peer *Peer) error { } defer msg.Discard() start := time.Now() - // Track the emount of time it takes to serve the request and run the handler + // Track the amount of time it takes to serve the request and run the handler if metrics.Enabled { h := fmt.Sprintf("%s/%s/%d/%#02x", p2p.HandleHistName, ProtocolName, peer.Version(), msg.Code) defer func(start time.Time) { diff --git a/eth/protocols/diff/handler_test.go b/eth/protocols/diff/handler_test.go index 5244687331..17af5a0012 100644 --- a/eth/protocols/diff/handler_test.go +++ b/eth/protocols/diff/handler_test.go @@ -134,9 +134,9 @@ func testGetDiffLayers(t *testing.T, protocol uint) { missDiffPackets := make([]FullDiffLayersPacket, 0) for i := 0; i < 100; i++ { - number := uint64(rand.Int63n(1024)) - if number == 0 { - continue + // Find a non 0 random number + var number uint64 + for ; number == 0; number = uint64(rand.Int63n(1024)) { } foundHash := backend.chain.GetCanonicalHash(number + 1024) missHash := backend.chain.GetCanonicalHash(number) diff --git a/eth/protocols/eth/handler.go b/eth/protocols/eth/handler.go index 81d45d8b8f..9eb949f139 100644 --- a/eth/protocols/eth/handler.go +++ b/eth/protocols/eth/handler.go @@ -195,9 +195,6 @@ func handleMessage(backend Backend, peer *Peer) error { defer msg.Discard() var handlers = eth66 - //if peer.Version() >= ETH67 { // Left in as a sample when new protocol is added - // handlers = eth67 - //} // Track the amount of time it takes to serve the request and run the handler if metrics.Enabled { diff --git a/eth/protocols/eth/handler_test.go b/eth/protocols/eth/handler_test.go index 55e612b801..b12be49bbf 100644 --- a/eth/protocols/eth/handler_test.go +++ b/eth/protocols/eth/handler_test.go @@ -94,8 +94,8 @@ func (b *testBackend) Chain() *core.BlockChain { return b.chain } func (b *testBackend) TxPool() TxPool { return b.txpool } func (b *testBackend) RunPeer(peer *Peer, handler Handler) error { - // Normally the backend would do peer mainentance and handshakes. All that - // is omitted and we will just give control back to the handler. + // Normally the backend would do peer maintenance and handshakes. All that + // is omitted, and we will just give control back to the handler. return handler(peer) } func (b *testBackend) PeerInfo(enode.ID) interface{} { panic("not implemented") } @@ -247,7 +247,7 @@ func testGetBlockHeaders(t *testing.T, protocol uint) { backend.chain.GetBlockByNumber(1).Hash(), }, }, - // Check that non existing headers aren't returned + // Check that non-existing headers aren't returned { &GetBlockHeadersPacket{Origin: HashOrNumber{Hash: unknown}, Amount: 1}, []common.Hash{}, diff --git a/eth/protocols/eth/peer.go b/eth/protocols/eth/peer.go index 8bf973f9c3..b39aa56eee 100644 --- a/eth/protocols/eth/peer.go +++ b/eth/protocols/eth/peer.go @@ -122,7 +122,6 @@ func NewPeer(version uint, p *p2p.Peer, rw p2p.MsgReadWriter, txpool TxPool) *Pe go peer.broadcastTransactions() go peer.announceTransactions() go peer.dispatcher() - return peer } @@ -149,7 +148,7 @@ func (p *Peer) ID() string { return p.id } -// Version retrieves the peer's negoatiated `eth` protocol version. +// Version retrieves the peer's negotiated `eth` protocol version. func (p *Peer) Version() uint { return p.version } @@ -324,6 +323,11 @@ func (p *Peer) AsyncSendNewBlock(block *types.Block, td *big.Int) { } } +// SendBlockHeaders sends a batch of block headers to the remote peer. +func (p *Peer) SendBlockHeaders(headers []*types.Header) error { + return p2p.Send(p.rw, BlockHeadersMsg, BlockHeadersPacket(headers)) +} + // ReplyBlockHeaders is the eth/66 version of SendBlockHeaders. func (p *Peer) ReplyBlockHeadersRLP(id uint64, headers []rlp.RawValue) error { return p2p.Send(p.rw, BlockHeadersMsg, &BlockHeadersRLPPacket66{ diff --git a/eth/protocols/eth/protocol.go b/eth/protocols/eth/protocol.go index 66ff9220cc..3e171d6f3e 100644 --- a/eth/protocols/eth/protocol.go +++ b/eth/protocols/eth/protocol.go @@ -202,7 +202,7 @@ func (hn *HashOrNumber) DecodeRLP(s *rlp.Stream) error { // BlockHeadersPacket represents a block header response. type BlockHeadersPacket []*types.Header -// BlockHeadersPacket represents a block header response over eth/66. +// BlockHeadersPacket66 represents a block header response over eth/66. type BlockHeadersPacket66 struct { RequestId uint64 BlockHeadersPacket @@ -240,7 +240,7 @@ func (request *NewBlockPacket) sanityCheck() error { // GetBlockBodiesPacket represents a block body query. type GetBlockBodiesPacket []common.Hash -// GetBlockBodiesPacket represents a block body query over eth/66. +// GetBlockBodiesPacket66 represents a block body query over eth/66. type GetBlockBodiesPacket66 struct { RequestId uint64 GetBlockBodiesPacket @@ -249,7 +249,7 @@ type GetBlockBodiesPacket66 struct { // BlockBodiesPacket is the network packet for block content distribution. type BlockBodiesPacket []*BlockBody -// BlockBodiesPacket is the network packet for block content distribution over eth/66. +// BlockBodiesPacket66 is the network packet for block content distribution over eth/66. type BlockBodiesPacket66 struct { RequestId uint64 BlockBodiesPacket @@ -288,7 +288,7 @@ func (p *BlockBodiesPacket) Unpack() ([][]*types.Transaction, [][]*types.Header) // GetNodeDataPacket represents a trie node data query. type GetNodeDataPacket []common.Hash -// GetNodeDataPacket represents a trie node data query over eth/66. +// GetNodeDataPacket66 represents a trie node data query over eth/66. type GetNodeDataPacket66 struct { RequestId uint64 GetNodeDataPacket @@ -297,7 +297,7 @@ type GetNodeDataPacket66 struct { // NodeDataPacket is the network packet for trie node data distribution. type NodeDataPacket [][]byte -// NodeDataPacket is the network packet for trie node data distribution over eth/66. +// NodeDataPacket66 is the network packet for trie node data distribution over eth/66. type NodeDataPacket66 struct { RequestId uint64 NodeDataPacket @@ -306,7 +306,7 @@ type NodeDataPacket66 struct { // GetReceiptsPacket represents a block receipts query. type GetReceiptsPacket []common.Hash -// GetReceiptsPacket represents a block receipts query over eth/66. +// GetReceiptsPacket66 represents a block receipts query over eth/66. type GetReceiptsPacket66 struct { RequestId uint64 GetReceiptsPacket @@ -315,7 +315,7 @@ type GetReceiptsPacket66 struct { // ReceiptsPacket is the network packet for block receipts distribution. type ReceiptsPacket [][]*types.Receipt -// ReceiptsPacket is the network packet for block receipts distribution over eth/66. +// ReceiptsPacket66 is the network packet for block receipts distribution over eth/66. type ReceiptsPacket66 struct { RequestId uint64 ReceiptsPacket @@ -324,7 +324,7 @@ type ReceiptsPacket66 struct { // ReceiptsRLPPacket is used for receipts, when we already have it encoded type ReceiptsRLPPacket []rlp.RawValue -// ReceiptsPacket66 is the eth-66 version of ReceiptsRLPPacket +// ReceiptsRLPPacket66 is the eth-66 version of ReceiptsRLPPacket type ReceiptsRLPPacket66 struct { RequestId uint64 ReceiptsRLPPacket @@ -344,13 +344,13 @@ type GetPooledTransactionsPacket66 struct { // PooledTransactionsPacket is the network packet for transaction distribution. type PooledTransactionsPacket []*types.Transaction -// PooledTransactionsPacket is the network packet for transaction distribution over eth/66. +// PooledTransactionsPacket66 is the network packet for transaction distribution over eth/66. type PooledTransactionsPacket66 struct { RequestId uint64 PooledTransactionsPacket } -// PooledTransactionsPacket is the network packet for transaction distribution, used +// PooledTransactionsRLPPacket is the network packet for transaction distribution, used // in the cases we already have them in rlp-encoded form type PooledTransactionsRLPPacket []rlp.RawValue diff --git a/eth/sync.go b/eth/sync.go index 22e2b293fe..a32d305c77 100644 --- a/eth/sync.go +++ b/eth/sync.go @@ -60,6 +60,15 @@ func (h *handler) syncTransactions(p *eth.Peer) { p.AsyncSendPooledTransactionHashes(hashes) } +// syncVotes starts sending all currently pending votes to the given peer. +func (h *handler) syncVotes(p *bscPeer) { + votes := h.votepool.GetVotes() + if len(votes) == 0 { + return + } + p.AsyncSendVotes(votes) +} + // chainSyncer coordinates blockchain sync components. type chainSyncer struct { handler *handler diff --git a/eth/tracers/js/tracer_test.go b/eth/tracers/js/tracer_test.go index 4389004dcc..b58b5ae94a 100644 --- a/eth/tracers/js/tracer_test.go +++ b/eth/tracers/js/tracer_test.go @@ -103,15 +103,15 @@ func TestTracer(t *testing.T) { { // tests that we don't panic on bad arguments to memory access code: "{depths: [], step: function(log) { this.depths.push(log.memory.slice(-1,-2)); }, fault: function() {}, result: function() { return this.depths; }}", want: ``, - fail: "Tracer accessed out of bound memory: offset -1, end -2 at step (:1:53(15)) in server-side tracer function 'step'", + fail: "Tracer accessed out of bound memory: offset -1, end -2 at step (:1:53(13)) in server-side tracer function 'step'", }, { // tests that we don't panic on bad arguments to stack peeks code: "{depths: [], step: function(log) { this.depths.push(log.stack.peek(-1)); }, fault: function() {}, result: function() { return this.depths; }}", want: ``, - fail: "Tracer accessed out of bound stack: size 0, index -1 at step (:1:53(13)) in server-side tracer function 'step'", + fail: "Tracer accessed out of bound stack: size 0, index -1 at step (:1:53(11)) in server-side tracer function 'step'", }, { // tests that we don't panic on bad arguments to memory getUint code: "{ depths: [], step: function(log, db) { this.depths.push(log.memory.getUint(-64));}, fault: function() {}, result: function() { return this.depths; }}", want: ``, - fail: "Tracer accessed out of bound memory: available 0, offset -64, size 32 at step (:1:58(13)) in server-side tracer function 'step'", + fail: "Tracer accessed out of bound memory: available 0, offset -64, size 32 at step (:1:58(11)) in server-side tracer function 'step'", }, { // tests some general counting code: "{count: 0, step: function() { this.count += 1; }, fault: function() {}, result: function() { return this.count; }}", want: `3`, diff --git a/ethclient/ethclient.go b/ethclient/ethclient.go index db388a3d9d..745a371e6a 100644 --- a/ethclient/ethclient.go +++ b/ethclient/ethclient.go @@ -29,6 +29,7 @@ import ( "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/internal/ethapi" "github.com/ethereum/go-ethereum/rpc" ) @@ -370,6 +371,17 @@ func (ec *Client) SubscribeNewHead(ctx context.Context, ch chan<- *types.Header) return ec.c.EthSubscribe(ctx, ch, "newHeads") } +// SubscribeNewFinalizedHeader subscribes to notifications about the current blockchain finalized header +// on the given channel. +func (ec *Client) SubscribeNewFinalizedHeader(ctx context.Context, ch chan<- *types.Header) (ethereum.Subscription, error) { + return ec.c.EthSubscribe(ctx, ch, "newFinalizedHeaders") +} + +// SubscribeNewVotes subscribes to notifications about the new votes into vote pool +func (ec *Client) SubscribeNewVotes(ctx context.Context, ch chan<- *types.VoteEnvelope) (ethereum.Subscription, error) { + return ec.c.EthSubscribe(ctx, ch, "newVotes") +} + // State Access // NetworkID returns the network ID (also known as the chain ID) for this chain. @@ -571,6 +583,18 @@ func (ec *Client) SendTransaction(ctx context.Context, tx *types.Transaction) er return ec.c.CallContext(ctx, nil, "eth_sendRawTransaction", hexutil.Encode(data)) } +// SendTransactionConditional injects a signed transaction into the pending pool for execution. +// +// If the transaction was a contract creation use the TransactionReceipt method to get the +// contract address after the transaction has been mined. +func (ec *Client) SendTransactionConditional(ctx context.Context, tx *types.Transaction, opts ethapi.TransactionOpts) error { + data, err := tx.MarshalBinary() + if err != nil { + return err + } + return ec.c.CallContext(ctx, nil, "eth_sendRawTransactionConditional", hexutil.Encode(data), opts) +} + func toBlockNumArg(number *big.Int) string { if number == nil { return "latest" @@ -579,6 +603,14 @@ func toBlockNumArg(number *big.Int) string { if number.Cmp(pending) == 0 { return "pending" } + finalized := big.NewInt(int64(rpc.FinalizedBlockNumber)) + if number.Cmp(finalized) == 0 { + return "finalized" + } + safe := big.NewInt(int64(rpc.SafeBlockNumber)) + if number.Cmp(safe) == 0 { + return "safe" + } return hexutil.EncodeBig(number) } diff --git a/ethclient/ethclient_test.go b/ethclient/ethclient_test.go index b488487620..355905d950 100644 --- a/ethclient/ethclient_test.go +++ b/ethclient/ethclient_test.go @@ -36,6 +36,7 @@ import ( "github.com/ethereum/go-ethereum/eth" "github.com/ethereum/go-ethereum/eth/ethconfig" "github.com/ethereum/go-ethereum/ethdb/memorydb" + "github.com/ethereum/go-ethereum/internal/ethapi" "github.com/ethereum/go-ethereum/node" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rpc" @@ -376,6 +377,9 @@ func TestEthClient(t *testing.T) { "TestDiffAccounts": { func(t *testing.T) { testDiffAccounts(t, client) }, }, + "TestSendTransactionConditional": { + func(t *testing.T) { testSendTransactionConditional(t, client) }, + }, // DO not have TestAtFunctions now, because we do not have pending block now } @@ -660,3 +664,45 @@ func testDiffAccounts(t *testing.T, client *rpc.Client) { } } } + +func testSendTransactionConditional(t *testing.T, client *rpc.Client) { + ec := NewClient(client) + + if err := sendTransactionConditional(ec); err != nil { + t.Fatalf("error: %v", err) + } +} + +func sendTransactionConditional(ec *Client) error { + chainID, err := ec.ChainID(context.Background()) + if err != nil { + return err + } + + nonce, err := ec.PendingNonceAt(context.Background(), testAddr) + if err != nil { + return err + } + + signer := types.LatestSignerForChainID(chainID) + + tx, err := types.SignNewTx(testKey, signer, &types.LegacyTx{ + Nonce: nonce, + To: &common.Address{2}, + Value: big.NewInt(1), + Gas: 22000, + GasPrice: big.NewInt(params.InitialBaseFee), + }) + if err != nil { + return err + } + + root := common.HexToHash("0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421") + return ec.SendTransactionConditional(context.Background(), tx, ethapi.TransactionOpts{ + KnownAccounts: map[common.Address]ethapi.AccountStorage{ + testAddr: ethapi.AccountStorage{ + StorageRoot: &root, + }, + }, + }) +} diff --git a/ethclient/gethclient/gethclient.go b/ethclient/gethclient/gethclient.go index 7af2bf45d7..3795b182e1 100644 --- a/ethclient/gethclient/gethclient.go +++ b/ethclient/gethclient/gethclient.go @@ -188,6 +188,14 @@ func toBlockNumArg(number *big.Int) string { if number.Cmp(pending) == 0 { return "pending" } + finalized := big.NewInt(int64(rpc.FinalizedBlockNumber)) + if number.Cmp(finalized) == 0 { + return "finalized" + } + safe := big.NewInt(int64(rpc.SafeBlockNumber)) + if number.Cmp(safe) == 0 { + return "safe" + } return hexutil.EncodeBig(number) } diff --git a/go.mod b/go.mod index 8405c9661a..8de86c0b9f 100644 --- a/go.mod +++ b/go.mod @@ -4,123 +4,276 @@ go 1.19 require ( github.com/Azure/azure-storage-blob-go v0.7.0 - github.com/VictoriaMetrics/fastcache v1.6.0 - github.com/aws/aws-sdk-go-v2 v1.2.0 + github.com/VictoriaMetrics/fastcache v1.12.0 + github.com/aws/aws-sdk-go-v2 v1.17.8 github.com/aws/aws-sdk-go-v2/config v1.1.1 github.com/aws/aws-sdk-go-v2/credentials v1.1.1 github.com/aws/aws-sdk-go-v2/service/route53 v1.1.1 github.com/bnb-chain/ics23 v0.1.0 - github.com/cespare/cp v0.1.0 + github.com/btcsuite/btcd/btcec/v2 v2.3.2 + github.com/cespare/cp v1.1.1 github.com/cloudflare/cloudflare-go v0.14.0 + github.com/cometbft/cometbft v0.37.0 github.com/consensys/gnark-crypto v0.4.1-0.20210426202927-39ac3d4b3f1f github.com/davecgh/go-spew v1.1.1 github.com/deckarep/golang-set v1.8.0 github.com/deepmap/oapi-codegen v1.8.2 // indirect - github.com/docker/docker v1.6.1 - github.com/dop251/goja v0.0.0-20220405120441-9037c2b61cbf - github.com/edsrzf/mmap-go v1.0.0 - github.com/fatih/color v1.7.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/etcd-io/bbolt v1.3.3 // indirect + github.com/fatih/color v1.13.0 + github.com/fatih/structs v1.1.0 github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 - github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff - github.com/go-stack/stack v1.8.0 + github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 + github.com/go-stack/stack v1.8.1 github.com/golang/protobuf v1.5.2 github.com/golang/snappy v0.0.4 github.com/google/gofuzz v1.2.0 - github.com/google/pprof v0.0.0-20220829040838-70bd9ae97f40 - github.com/google/uuid v1.1.5 + github.com/google/pprof v0.0.0-20221203041831-ce31453925ec + github.com/google/uuid v1.3.0 github.com/gorilla/websocket v1.5.0 github.com/graph-gophers/graphql-go v1.3.0 github.com/hashicorp/go-bexpr v0.1.10 github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d github.com/holiman/bloomfilter/v2 v2.0.3 - github.com/holiman/uint256 v1.2.0 + github.com/holiman/uint256 v1.2.1 github.com/huin/goupnp v1.0.3 github.com/influxdata/influxdb v1.8.3 github.com/influxdata/influxdb-client-go/v2 v2.4.0 github.com/jackpal/go-nat-pmp v1.0.2 github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e + github.com/jmhodges/levigo v1.0.0 // indirect github.com/julienschmidt/httprouter v1.3.0 github.com/karalabe/usb v0.0.2 - github.com/mattn/go-colorable v0.1.8 - github.com/mattn/go-isatty v0.0.12 + github.com/logrusorgru/aurora v2.0.3+incompatible + github.com/mattn/go-colorable v0.1.13 + github.com/mattn/go-isatty v0.0.16 github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416 github.com/olekukonko/tablewriter v0.0.5 github.com/panjf2000/ants/v2 v2.4.5 - github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7 - github.com/pkg/errors v0.9.1 // indirect - github.com/prometheus/tsdb v0.7.1 + github.com/peterh/liner v1.2.0 + github.com/pkg/errors v0.9.1 + github.com/prometheus/tsdb v0.10.0 + github.com/prysmaticlabs/prysm/v3 v3.2.1 github.com/rjeczalik/notify v0.9.1 - github.com/rs/cors v1.7.0 + github.com/rs/cors v1.8.2 github.com/shirou/gopsutil v3.21.11+incompatible - github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4 + github.com/status-im/keycard-go v0.2.0 github.com/stretchr/testify v1.8.1 - github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 + github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d github.com/tendermint/go-amino v0.14.1 github.com/tendermint/iavl v0.12.0 - github.com/tendermint/tendermint v0.31.12 - github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef + github.com/tendermint/tendermint v0.31.15 + github.com/tidwall/wal v1.1.7 + github.com/tyler-smith/go-bip39 v1.1.0 + github.com/wealdtech/go-eth2-wallet-encryptor-keystorev4 v1.1.3 + github.com/willf/bitset v1.1.3 golang.org/x/crypto v0.5.0 golang.org/x/sync v0.1.0 - golang.org/x/sys v0.4.0 - golang.org/x/text v0.6.0 - golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba - golang.org/x/tools v0.1.12 + golang.org/x/sys v0.6.0 + golang.org/x/text v0.8.0 + golang.org/x/time v0.0.0-20220922220347-f3bd1da661af + golang.org/x/tools v0.6.0 gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce gopkg.in/urfave/cli.v1 v1.20.0 ) require ( - github.com/btcsuite/btcd/btcec/v2 v2.3.2 - github.com/fatih/structs v1.1.0 -) - -require ( + contrib.go.opencensus.io/exporter/jaeger v0.2.1 // indirect github.com/Azure/azure-pipeline-go v0.2.2 // indirect - github.com/Azure/go-autorest/autorest/adal v0.8.0 // indirect + github.com/BurntSushi/toml v1.2.1 // indirect + github.com/aristanetworks/goarista v0.0.0-20200805130819-fd197cf57d96 // indirect github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.0.2 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.3.33 // indirect github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.0.2 // indirect github.com/aws/aws-sdk-go-v2/service/sso v1.1.1 // indirect github.com/aws/aws-sdk-go-v2/service/sts v1.1.1 // indirect - github.com/aws/smithy-go v1.1.0 // indirect + github.com/aws/smithy-go v1.13.5 // indirect + github.com/benbjohnson/clock v1.3.0 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/cespare/xxhash/v2 v2.1.2 // indirect - github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect - github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91 // indirect - github.com/etcd-io/bbolt v1.3.3 // indirect - github.com/fortytw2/leaktest v1.3.0 // indirect - github.com/go-kit/kit v0.9.0 // indirect + github.com/cespare/xxhash v1.1.0 // indirect + github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/chzyer/readline v1.5.0 // indirect + github.com/containerd/cgroups v1.0.4 // 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/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.0 // indirect + github.com/elastic/gosigar v0.14.2 // 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.6.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-ole/go-ole v1.2.6 // indirect + github.com/go-playground/locales v0.14.0 // indirect + github.com/go-playground/universal-translator v0.18.0 // indirect + github.com/go-playground/validator/v10 v10.11.1 // indirect github.com/go-sourcemap/sourcemap v2.1.3+incompatible // 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-jwt/jwt/v4 v4.3.0 // indirect + github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect + github.com/golang/mock v1.6.0 // indirect + github.com/google/go-cmp v0.5.9 // indirect + github.com/google/gopacket v1.1.19 // indirect + github.com/gorilla/mux v1.8.0 // indirect + github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect + github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.0.1 // indirect + github.com/gtank/merlin v0.1.1 // indirect + github.com/herumi/bls-eth-go-binary v0.0.0-20210917013441-d37c07cfda4e // indirect github.com/influxdata/line-protocol v0.0.0-20210311194329-9aa0e372d097 // indirect - github.com/jmhodges/levigo v1.0.0 // indirect - github.com/kylelemons/godebug v1.1.0 // indirect + github.com/ipfs/go-cid v0.3.2 // indirect + github.com/ipfs/go-log v1.0.5 // indirect + github.com/ipfs/go-log/v2 v2.5.1 // indirect + github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a // indirect + github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213 // indirect + github.com/klauspost/compress v1.15.15 // indirect + github.com/klauspost/cpuid/v2 v2.2.1 // indirect + github.com/koron/go-ssdp v0.0.3 // indirect + github.com/kr/pretty v0.3.1 // indirect + github.com/kr/text v0.2.0 // indirect + github.com/leodido/go-urn v1.2.1 // indirect + github.com/libp2p/go-buffer-pool v0.1.0 // indirect + github.com/libp2p/go-cidranger v1.1.0 // indirect + github.com/libp2p/go-flow-metrics v0.1.0 // indirect + github.com/libp2p/go-libp2p v0.24.0 // indirect + github.com/libp2p/go-libp2p-asn-util v0.2.0 // indirect + github.com/libp2p/go-libp2p-pubsub v0.8.0 // indirect + github.com/libp2p/go-mplex v0.7.0 // indirect + github.com/libp2p/go-msgio v0.2.0 // indirect + github.com/libp2p/go-nat v0.1.0 // indirect + github.com/libp2p/go-netroute v0.2.1 // indirect + github.com/libp2p/go-openssl v0.1.0 // indirect + github.com/libp2p/go-reuseport v0.2.0 // indirect + github.com/libp2p/go-yamux/v4 v4.0.0 // indirect + github.com/lucas-clemente/quic-go v0.31.0 // indirect + github.com/lunixbochs/vtclean v1.0.0 // indirect + github.com/manifoldco/promptui v0.7.0 // indirect + github.com/marten-seemann/qtls-go1-18 v0.1.3 // indirect + github.com/marten-seemann/qtls-go1-19 v0.1.1 // indirect + github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d // indirect - github.com/mattn/go-runewidth v0.0.9 // indirect - github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect - github.com/mitchellh/mapstructure v1.4.1 // indirect + github.com/mattn/go-pointer v0.0.1 // indirect + github.com/mattn/go-runewidth v0.0.14 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect + 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/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0 // indirect + github.com/minio/highwayhash v1.0.2 // indirect + github.com/minio/sha256-simd v1.0.0 // indirect + github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect + github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mitchellh/pointerstructure v1.2.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/multiformats/go-base32 v0.1.0 // indirect + github.com/multiformats/go-base36 v0.2.0 // indirect + github.com/multiformats/go-multiaddr v0.8.0 // indirect + github.com/multiformats/go-multiaddr-dns v0.3.1 // indirect + github.com/multiformats/go-multiaddr-fmt v0.1.0 // indirect + github.com/multiformats/go-multibase v0.1.1 // indirect + github.com/multiformats/go-multicodec v0.7.0 // indirect + github.com/multiformats/go-multihash v0.2.1 // indirect + github.com/multiformats/go-multistream v0.3.3 // indirect + github.com/multiformats/go-varint v0.0.7 // indirect github.com/naoina/go-stringutil v0.1.0 // indirect - github.com/opentracing/opentracing-go v1.1.0 // indirect + github.com/onsi/ginkgo/v2 v2.5.1 // indirect + github.com/opencontainers/runtime-spec v1.0.2 // indirect + github.com/opentracing/opentracing-go v1.2.0 // indirect + github.com/patrickmn/go-cache v2.1.0+incompatible // indirect + github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect + github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_golang v1.14.0 // indirect github.com/prometheus/client_model v0.3.0 // indirect - github.com/prometheus/common v0.37.0 // indirect - github.com/prometheus/procfs v0.8.0 // indirect - github.com/rcrowley/go-metrics v0.0.0-20190826022208-cac0b30c2563 // indirect - github.com/tklauser/go-sysconf v0.3.5 // indirect - github.com/tklauser/numcpus v0.2.2 // indirect + github.com/prometheus/common v0.39.0 // indirect + github.com/prometheus/procfs v0.9.0 // indirect + github.com/prometheus/prom2json v1.3.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/go-bitfield v0.0.0-20210809151128-385d8c5e3fb7 // indirect + github.com/prysmaticlabs/gohashtree v0.0.2-alpha // indirect + github.com/prysmaticlabs/prombbolt v0.0.0-20210126082820-9b7adba6db7c // indirect + github.com/prysmaticlabs/prysm v0.0.0-20220124113610-e26cde5e091b // indirect + github.com/r3labs/sse v0.0.0-20210224172625-26fe804710bc // indirect + github.com/raulk/go-watchdog v1.3.0 // indirect + github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect + github.com/rivo/uniseg v0.4.3 // indirect + github.com/rogpeppe/go-internal v1.9.0 // indirect + github.com/russross/blackfriday/v2 v2.1.0 // indirect + github.com/sasha-s/go-deadlock v0.3.1 // indirect + github.com/schollz/progressbar/v3 v3.3.4 // indirect + github.com/sirupsen/logrus v1.9.0 // indirect + github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 // indirect + github.com/spaolacci/murmur3 v1.1.0 // indirect + github.com/supranational/blst v0.3.8-0.20220526154634-513d2456b344 // indirect + github.com/thomaso-mirodin/intmath v0.0.0-20160323211736-5dc6d854e46e // indirect + github.com/tidwall/gjson v1.10.2 // indirect + github.com/tidwall/match v1.1.1 // indirect + github.com/tidwall/pretty v1.2.0 // indirect + github.com/tidwall/tinylru v1.1.0 // indirect + github.com/tklauser/go-sysconf v0.3.11 // indirect + github.com/tklauser/numcpus v0.6.0 // indirect + github.com/trailofbits/go-mutexasserts v0.0.0-20200708152505-19999e7d3cef // indirect + github.com/uber/jaeger-client-go v2.25.0+incompatible // indirect + github.com/urfave/cli/v2 v2.23.7 // indirect + github.com/wealdtech/go-bytesutil v1.1.1 // indirect + github.com/wealdtech/go-eth2-types/v2 v2.5.2 // indirect + github.com/wealdtech/go-eth2-util v1.6.3 // indirect + github.com/whyrusleeping/timecache v0.0.0-20160911033111-cfcb2f1abfee // 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.7 // indirect - golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect - golang.org/x/net v0.5.0 // indirect - golang.org/x/term v0.4.0 // indirect - google.golang.org/genproto v0.0.0-20200825200019-8632dd797987 // indirect - google.golang.org/grpc v1.31.0 // indirect - google.golang.org/protobuf v1.28.1 // indirect + go.opencensus.io v0.24.0 // indirect + go.uber.org/atomic v1.10.0 // indirect + go.uber.org/dig v1.15.0 // indirect + go.uber.org/fx v1.18.2 // indirect + go.uber.org/multierr v1.8.0 // indirect + go.uber.org/zap v1.24.0 // indirect + golang.org/x/exp v0.0.0-20230206171751-46f607a40771 // indirect + golang.org/x/mod v0.8.0 // indirect + golang.org/x/net v0.7.0 // indirect + golang.org/x/oauth2 v0.3.0 // indirect + golang.org/x/term v0.6.0 // indirect + google.golang.org/api v0.34.0 // indirect + google.golang.org/appengine v1.6.7 // indirect + google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect + google.golang.org/grpc v1.52.0 // indirect + google.golang.org/protobuf v1.28.2-0.20220831092852-f930b1dc76e8 // indirect + gopkg.in/cenkalti/backoff.v1 v1.1.0 // indirect + gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect + k8s.io/apimachinery v0.18.3 // indirect + k8s.io/client-go v0.18.3 // indirect + k8s.io/klog v1.0.0 // indirect + k8s.io/klog/v2 v2.80.0 // indirect + k8s.io/utils v0.0.0-20200520001619-278ece378a50 // indirect + lukechampine.com/blake3 v1.1.7 // indirect + sigs.k8s.io/structured-merge-diff/v3 v3.0.0 // indirect + sigs.k8s.io/yaml v1.2.0 // indirect ) -replace github.com/tendermint/tendermint => github.com/bnb-chain/tendermint v0.31.15 +replace ( + github.com/btcsuite/btcd => github.com/btcsuite/btcd v0.23.0 + github.com/cometbft/cometbft => github.com/bnb-chain/greenfield-tendermint v0.0.0-20230417032003-4cda1f296fb2 + github.com/grpc-ecosystem/grpc-gateway/v2 => github.com/prysmaticlabs/grpc-gateway/v2 v2.3.1-0.20210702154020-550e1cd83ec1 + github.com/tendermint/tendermint => github.com/bnb-chain/tendermint v0.31.15 +) diff --git a/go.sum b/go.sum index 5ce59554c8..a0e0bf66e5 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,8 @@ +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= @@ -24,6 +27,7 @@ cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM7 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/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= 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= @@ -34,7 +38,16 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl 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 h1:yGBYzYMewVL0yO9qqJv3Z5+IRhPdU7e9o/2oKpX4YvI= +contrib.go.opencensus.io/exporter/jaeger v0.2.1/go.mod h1:Y8IsLgdxqh1QxYxPC5IgXVmBaeLUeQFfBeBi9PbeZd0= +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= +git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg= +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 h1:6oiIS9yaG6XCCzhgAgKFfIWyo4LLCiDhZot6ltoThhY= github.com/Azure/azure-pipeline-go v0.2.2/go.mod h1:4rQ/NZncSvGqNkkOsNpOU1tgoNuIlp9AfUH5G1tvCHc= @@ -56,31 +69,69 @@ github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6L github.com/Azure/go-autorest/tracing v0.5.0 h1:TRn4WjSnkcSy5AEG3pnbtFSwNtwzjr4VYyQflFE619k= 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/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak= +github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= 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/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/VictoriaMetrics/fastcache v1.6.0 h1:C/3Oi3EiBCqufydp1neRZkqcwmEiuRT9c3fqvvgKm5o= +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/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.0 h1:vnVi/y9yKDcD9akmc4NqAoqgQhJrOwUF+j9LTgn4QDE= +github.com/VictoriaMetrics/fastcache v1.12.0/go.mod h1:tjiYeEfYXCqacuvYw/7UoDIeJaNxq6132xHICNP77w8= 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/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= 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/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= -github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8= 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/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/aws/aws-sdk-go-v2 v1.2.0 h1:BS+UYpbsElC82gB+2E2jiCBg36i8HlubTB/dO/moQ9c= +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/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/goarista v0.0.0-20200805130819-fd197cf57d96 h1:XJH0YfVFKbq782tlNThzN/Ud5qm/cx6LXOA/P6RkTxc= +github.com/aristanetworks/goarista v0.0.0-20200805130819-fd197cf57d96/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 v1.17.8 h1:GMupCNNI7FARX27L7GjCJM8NgivWbRgpjNI/hOQjFS8= +github.com/aws/aws-sdk-go-v2 v1.17.8/go.mod h1:uzbQtefpm44goOPmdKyAlXSNcwlRgF3ePWVW6EtJvvw= github.com/aws/aws-sdk-go-v2/config v1.1.1 h1:ZAoq32boMzcaTW9bcUacBswAmHTbvlvDJICgHFZuECo= 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 h1:NbvWIM1Mx6sNPTxowHgS2ewXCRp+NGTzUYb/96FZJbY= 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 h1:EtEU7WRaWliitZh2nmuxEXrN0Cb8EgPUFGIoTMeqbzI= 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/internal/ini v1.3.33 h1:HbH1VjUgrCdLJ+4lnnuLI4iVNRvBbBELGaJ5f69ClA8= +github.com/aws/aws-sdk-go-v2/internal/ini v1.3.33/go.mod h1:zG2FcwjQarWaqXSCGpgcr3RSjZ6dHGguZSppUL0XR7Q= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.0.2 h1:4AH9fFjUlVktQMznF+YN33aWNXaR4VgDXyP28qokJC0= 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 h1:cKr6St+CtC3/dl/rEBJvlk7A/IN5D5F02GNkGzfbtVU= @@ -89,138 +140,322 @@ github.com/aws/aws-sdk-go-v2/service/sso v1.1.1 h1:37QubsarExl5ZuCBlnRP+7l1tNwZP 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 h1:TJoIfnIFubCX0ACVeJ0w46HEH5MwjwYN4iFhuYIhfIY= 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 h1:D6CSsM3gdxaGaqXnPgOBCeL6Mophqzu7KJOu7zW78sU= github.com/aws/smithy-go v1.1.0/go.mod h1:EzMw8dbp/YJL4A5/sbhGddag+NPT7q084agLbB9LgIw= +github.com/aws/smithy-go v1.13.5 h1:hgz0X/DX0dGqTYpGALqXJoRKRj5oQ7150i5FdTePzO8= +github.com/aws/smithy-go v1.13.5/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= +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= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= 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/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ00z/TKoufEY6K/a0k6AhaJrQKdFe6OfVXsa4= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= 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/btcsuite/btcd v0.20.1-beta h1:Ik4hyJqN8Jfyv3S4AGBOmyouMsYE3EdYODkMbQjwPGw= -github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= +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/btcsuite/btcd v0.23.0 h1:V2/ZgjfDFIygAX3ZapeigkVBoVUtOJKSwrhZdlpSvaA= +github.com/btcsuite/btcd v0.23.0/go.mod h1:0QJIIN1wwIXF/3G/m87gIwGniDMDQqjVn4SZgnFpsYY= +github.com/btcsuite/btcd/btcec/v2 v2.1.0/go.mod h1:2VzYrv4Gm4apmbVVsSq5bqf1Ec8v56E48Vt0Y/umPgA= +github.com/btcsuite/btcd/btcec/v2 v2.1.3/go.mod h1:ctjw4H1kknNJmRN4iP1R7bTQ+v3GJkZBd6mui8ZsAZE= 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.0/go.mod h1:5OapHB7A2hBBWLm48mmw4MOHNJCcUBTwmWH/0Jn8VHE= github.com/btcsuite/btcd/btcutil v1.1.3 h1:xfbtw8lwpp0G6NwSHb+UE67ryTFHJAiNuipusjXSohQ= +github.com/btcsuite/btcd/chaincfg/chainhash v1.0.0/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= +github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U= +github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= -github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= 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= -github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= 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/bufbuild/buf v0.37.0/go.mod h1:lQ1m2HkIaGOFba6w/aC3KYBHhKEOESP3gaAEpS3dAFM= +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/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 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk= github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= +github.com/cespare/cp v1.1.1 h1:nCb6ZLdB7NRaqsm91JtQTAme2SKJzXVsdPIPkyJr1MU= +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.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= github.com/cespare/xxhash/v2 v2.1.2/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/cheekybits/genny v1.0.0/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/logex v1.2.0 h1:+eqR0HfOetur4tgnC8ftU5imRnhi4te+BadWS95c5AM= +github.com/chzyer/logex v1.2.0/go.mod h1:9+9sk7u7pGNWYMkh0hdiL++6OeibzJccyQU4p4MedaY= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/readline v1.5.0 h1:lSwwFrbNviGePhkewF1az4oLmcwqCZijQ2/Wi3BGHAI= +github.com/chzyer/readline v1.5.0/go.mod h1:x22KAscuvRqlLoK9CsoYsmxoXZMMFVyOl86cAH8qUic= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/chzyer/test v0.0.0-20210722231415-061457976a23 h1:dZ0/VyGgQdVGAss6Ju0dt5P0QltE0SFY5Woh6hbIfiQ= +github.com/chzyer/test v0.0.0-20210722231415-061457976a23/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 h1:gFqGlGl/5f9UGXAaKapCGUfaTCgRKKnzu2VvzMZlOFA= 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/gnark-crypto v0.4.1-0.20210426202927-39ac3d4b3f1f/go.mod h1:815PAHg3wvysy0SyIqanF8gZ0Y1wjk/hrDHD/iT88+Q= +github.com/containerd/cgroups v0.0.0-20201119153540-4cbc285b3327/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE= +github.com/containerd/cgroups v1.0.4 h1:jN/mbWBEaz+T1pi5OFtnkQ+8qnmEbAr1Oo1FRm5B0dA= +github.com/containerd/cgroups v1.0.4/go.mod h1:nLNQtsF7Sl2HxNebu77i1R0oDlhiTG+kO4JTrUzo6IA= +github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= +github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/etcd v3.3.13+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-20190321100706-95778dfbb74e/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/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/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/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/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1m5sE92cU+pd5Mcc= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= +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 h1:SegyeYGcdi0jLLrpbCMoJxnUUn8GBXHsvr4rbzjuhfU= 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 h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= 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/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 v1.6.1 h1:4xYASHy5cScPkLD7PO0uTmnVc860m9NarPN1X8zeMe8= -github.com/docker/docker v1.6.1/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -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/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/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 v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +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 h1:CEBF7HpRnUCSJgGUb5h1Gm7e3VkmVDrR8lvWVLtrOFw= 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/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= +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.20210217033140-668b12f5399d/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/etcd-io/bbolt v1.3.3 h1:gSJmxrs37LgTqR/oyJBWok6k6SvXEUerFTbltIhXkBM= github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw= -github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= +github.com/ethereum/go-ethereum v1.10.13/go.mod h1:W3yfrFyL9C1pHcwY5hmRHVDaorTiQxhYBkKyu5mEDHw= +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/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= +github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= +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/memsize v0.0.0-20190710130421-bcb5799ab5e5 h1:FtmdgXiUlNeRsoNMFlKLDt+S+6hbjVMEW6RGQ7aUf7c= 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/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 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff h1:tY80oXqGNY4FhTFhk+o9oFHGINQ/+vhlm8HFzi6znCI= +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/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 h1:f6D9Hr8xV8uYKlyuj8XIruxlh9WjVjdh1gIicAS7ays= +github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= 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/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/glycerine/go-unsnap-stream v0.0.0-20180323001048-9f0cb55181dd/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE= 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 h1:wDJmvq38kDhkVxi50ni9ykkdUr1PKgqKOoi01fa0Mdk= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +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.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= +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.0/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-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 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= +github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU= +github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs= +github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho= +github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA= +github.com/go-playground/validator/v10 v10.11.1 h1:prmOlTVv+YjZjmRmNSF3VmspqJIxJWXmqUsHwfTRRkQ= +github.com/go-playground/validator/v10 v10.11.1/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4dMGDBiPU55YFDl0WbKdWU= 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.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= +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 h1:RYi2hDdss1u4YE7GwixGzWwVo47T8UQwnTLB6vQiq+o= +github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0= +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.0/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gofrs/uuid v3.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/gofrs/uuid v4.0.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= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= 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.3.0 h1:kHL1vqdqWNfATmA0FNMdmZNMyZI1U6O31X4rlIPoBog= +github.com/golang-jwt/jwt/v4 v4.3.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= 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 h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= 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-20190129154638-5b532d6fd5ef/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/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/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= @@ -228,6 +463,9 @@ github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt 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= @@ -245,14 +483,18 @@ github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw 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/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-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/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= @@ -260,14 +502,26 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ 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.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +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.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= @@ -275,40 +529,113 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf 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-20220829040838-70bd9ae97f40 h1:ykKxL12NZd3JmWZnyqarJGsF73M9Xhtrik/FEtEeFRE= -github.com/google/pprof v0.0.0-20220829040838-70bd9ae97f40/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo= +github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20221203041831-ce31453925ec h1:fR20TYVVwhK4O7r7y+McjRYyaTH6/vjwJOajE+XhlzM= +github.com/google/pprof v0.0.0-20221203041831-ce31453925ec/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/uuid v1.1.5 h1:kxhtnfFVi+rYdOALN0B3k9UT86zVJKfBimRaciULW4I= +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/gordonklaus/ineffassign v0.0.0-20200309095847-7953dde2c7bf/go.mod h1:cuNKsD1zp2v6XfE/orVX2QE1LC+i254ceGcVeDT3pTU= +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 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= 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.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/graph-gophers/graphql-go v1.3.0 h1:Eb9x/q6MFpCLz7jBCiP/WTxjSDrYLR1QY41SORZyNJ0= github.com/graph-gophers/graphql-go v1.3.0/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.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +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.2.2/go.mod h1:EaizFBKfUKtMIF5iaDEhniwNedqGo9FuLFzppDr3uwI= +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-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= +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.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +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.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= +github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= +github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +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 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpxn4uE= 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= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +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/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/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= -github.com/holiman/uint256 v1.2.0 h1:gpSYcPLWGv4sG43I2mVLiDZCNDh/EpGjSk8tmtxitHM= github.com/holiman/uint256 v1.2.0/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw= +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/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +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.0.3 h1:N8No57ls+MnjlB+JPiCVSOyy/ot7MJTqlo7rn+NYSqQ= github.com/huin/goupnp v1.0.3/go.mod h1:ZxNlw5WqJj6wSsRK5+YfflQGXYfccj5VgQsMNixHM7Y= 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/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/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/influxdata/flux v0.65.1/go.mod h1:J754/zds0vvpfwuq7Gc2wRdVwEodfpCFM7mYlOw2LqY= github.com/influxdata/influxdb v1.8.3 h1:WEypI1BQFTT4teLM+1qkEcvUi0dAvopAI/ir0vAiBg8= github.com/influxdata/influxdb v1.8.3/go.mod h1:JugdFhsvvI8gadxOI6noqNeeBHvWNTbfYGtiAn+2jhI= github.com/influxdata/influxdb-client-go/v2 v2.4.0 h1:HGBfZYStlx3Kqvsv1h2pJixbCl/jhnFtxpKFAv9Tu5k= 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= @@ -318,47 +645,128 @@ github.com/influxdata/promql/v2 v2.12.0/go.mod h1:fxOPu+DY0bqCTCECchSRtWfc+0X19y 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 h1:2dOuUCB1Z7uoczMWgAyDck5JLb72zHzrMnGnCNNbvY8= +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 h1:UvSe12bq+Uj2hWd8aOlwPmoZ+CITRFrdit+sDGfAg8U= github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e/go.mod h1:G1CVv03EnqU1wYL2dFwXxW2An0az9JTl/ZsqXQeBlkU= -github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jhump/protoreflect v1.8.1/go.mod h1:7GcYQDdMU/O/BBrl/cX6PNHpXh6cenjd8pneu5yW7Tg= +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/jmhodges/levigo v1.0.0/go.mod h1:Q6Qx+uH3RAqyK4rFQroq9RL7mdkABMcfhEI+nNuzMJQ= +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.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a h1:FaWFmfWdAUKbSCtOU2QjDaorUexogfaMgbipgYATUMU= +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 h1:qGQQKEcAR99REcMpsXCp3lJ03zYT1PkRd3kQGPn9GVg= +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/karalabe/usb v0.0.2 h1:M6QQBNxF+CQ8OFvxrT90BA0qBOXymndZnk5q235mFc4= github.com/karalabe/usb v0.0.2/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU= +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.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.1 h1:U33DW0aiEj633gHYw3LoDNfkDiYnE5Q8M/TKJn2f2jI= +github.com/klauspost/cpuid/v2 v2.2.1/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/pgzip v1.2.5/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= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= +github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +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= @@ -368,135 +776,615 @@ github.com/labstack/echo/v4 v4.2.1/go.mod h1:AA49e0DZ8kk5jTOOCKNuPR6oTnBS0dYiM4F 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/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= +github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= 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.17.0/go.mod h1:Fkin50rsGdv5mm5BshBUtPRZknt9esfmYXBOYcwOTgw= +github.com/libp2p/go-libp2p v0.24.0 h1:DQk/5bBon+yUVIGTeRVBmOYpZzoBHx/VTC0xoLgJGG4= +github.com/libp2p/go-libp2p v0.24.0/go.mod h1:28t24CYDlnBs23rIs1OclU89YbhgibrBq2LFbMe+cFw= +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-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.8.0 h1:KygfDpaa9AeUPGCVcpVenpXNFauDn+5kBYu3EjcL3Tg= +github.com/libp2p/go-libp2p-pubsub v0.8.0/go.mod h1:e4kT+DYjzPUYGZeWk4I+oxCSYTXizzXii5LDRRhjKSw= +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.2.0 h1:W6shmB+FeynDrUVl2dgFQvzfBZcXiyqY4VmpQLu9FqU= +github.com/libp2p/go-msgio v0.2.0/go.mod h1:dBVM1gW3Jk9XqHkU4eKdGvVHdLa51hoGfll6jMJMSlY= +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-openssl v0.1.0 h1:LBkKEcUv6vtZIQLVTegAil8jbNpJErQ9AnT+bWV+Ooo= +github.com/libp2p/go-openssl v0.1.0/go.mod h1:OiOxwPpL3n4xlenjx2h7AwSGaFSC/KZvf6gNdOBQMtc= +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/logrusorgru/aurora v2.0.3+incompatible h1:tOpm7WcpBTn4fjmVfgpQq0EfczGlG91VSDkswnjF5A8= +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/lucas-clemente/quic-go v0.31.0 h1:MfNp3fk0wjWRajw6quMFA3ap1AVtlU+2mtwmbVogB2M= +github.com/lucas-clemente/quic-go v0.31.0/go.mod h1:0wFbizLgYzqHqtlyxyCaJKlE7bYgE6JQ+54TLd/Dq2g= +github.com/lunixbochs/vtclean v0.0.0-20180621232353-2d01aacdc34a/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= +github.com/lunixbochs/vtclean v1.0.0 h1:xu2sLAri4lGiovBDQKxl5mrXyESr3gUr5m5SM5+LVb8= +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.7.4-0.20170902060319-8d7837e64d3c/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/magiconair/properties v1.8.1/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 h1:3l11YT8tm9MnwGFQ4kETwkzpAwY2Jt9lCrumCUW4+z4= +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/qpack v0.3.0 h1:UiWstOgT8+znlkDPOg2+3rIuYXJ2CnGDkGUXN6ki6hE= +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/qtls-go1-18 v0.1.3 h1:R4H2Ks8P6pAtUagjFty2p7BVHn3XiwDAl7TTQf5h7TI= +github.com/marten-seemann/qtls-go1-18 v0.1.3/go.mod h1:mJttiymBAByA49mhlNZZGrH5u1uXYZJ+RW28Py7f4m4= +github.com/marten-seemann/qtls-go1-19 v0.1.1 h1:mnbxeq3oEyQxQXwI4ReCgW9DPoPR94sNlqWoDZnjRIE= +github.com/marten-seemann/qtls-go1-19 v0.1.1/go.mod h1:5HTDWtVudo/WFsHKRNuOhWlbdjrfs5JHrYb0wIJqGpI= +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/marten-seemann/webtransport-go v0.4.1 h1:8Ir7OoAvtp79yxQpa3foTKIPuoH+0eKpisHObJyu9Sk= 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 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8= github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.9/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 h1:oNAwILwmgWKFpuU+dXvI6dl9jG2mAWAZLX3r9s0PPiw= 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.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= +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 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-pointer v0.0.1 h1:n+XhsuGeVO6MEAp7xyEukFINEa+Quek5psIR/ylA6o0= +github.com/mattn/go-pointer v0.0.1/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc= +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 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= +github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-tty v0.0.0-20180907095812-13ff1204f104/go.mod h1:XPvLUNfbS4fJH25nqRHfWLMa1ONC8Amw+mIA639KxkE= -github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag= +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= +github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c/go.mod h1:0SQS9kMwD2VsyFEB++InYyBJroV/FRmBgcydeSUcJms= +github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= +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/highwayhash v1.0.2/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY= +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 h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ= +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 h1:O+i9nHnXS3l/9Wu7r4NrEdwA2VFTicjUEN1uBnDo34A= github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= 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= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= 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/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.7.0 h1:rTUjGOwjlhGHbEMbPoSUJowG1spZTVsITRANCjKTUAQ= +github.com/multiformats/go-multicodec v0.7.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.3.3 h1:d5PZpjwRgVlbwfdTDjife7XszfZd8KYWfROYFlGcR8o= +github.com/multiformats/go-multistream v0.3.3/go.mod h1:ODRoqamLUsETKS9BNcII4gcRsJBU5VAwRIv7O39cEXg= +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 h1:rCUeRUHjBjGTSHl0VC00jUPLz8/F9dDzYI70Hzifhks= 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 h1:shk/vn9oCoOTmwcouEdwIeOtOGA/ELRUw/GwvxwfT+0= github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416/go.mod h1:NBIhNtsFMo3G2szEBne+bO4gS192HuIYRqfvOWb4i1E= -github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= +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= +github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= +github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= +github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= +github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= +github.com/nishanths/predeclared v0.0.0-20200524104333-86fad755b4d3/go.mod h1:nt3d53pc1VYcphSCIaYAJtnPYnr3Zyn8fMq2wvPGPso= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +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 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= 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 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA= 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.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/ginkgo/v2 v2.5.1 h1:auzK7OI497k6x4OvWq+TKAcpcSAlod0doAH72oIN0Jw= +github.com/onsi/ginkgo/v2 v2.5.1/go.mod h1:63DOGlLAH8+REH8jUGdL3YpCpu7JODesutUjdENfUAc= +github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/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.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE= +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.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= +github.com/onsi/gomega v1.24.0 h1:+0glovB9Jd6z3VR+ScSwQqXVTIfJcGA9UBM8yzQxhqg= +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 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= +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= +github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= +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/panjf2000/ants/v2 v2.4.5 h1:kcGvjXB7ea0MrzzszpnlVFthhYKoFxLi75nRbsq01HY= github.com/panjf2000/ants/v2 v2.4.5/go.mod h1:f6F0NZVFsGCp5A7QW/Zj/m92atWwOkY0OIhFxRNFr4A= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= +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/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 h1:oYW+YCJ1pachXTQmzR3rNLYGGz4g/UgFcjb28p/viDM= github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0= +github.com/peterh/liner v1.2.0 h1:w/UPXyl5GfahFxcTOz2j9wCIHNI+pUPr2laqpojKNCg= +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/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 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/profile v1.5.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdLa18= 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/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 v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= 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.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.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= 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= +github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= 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.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.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= -github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE= -github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= +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= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= 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.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.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo= -github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= -github.com/prometheus/tsdb v0.7.1 h1:YZcsG11NqnK4czYLrWd9mpEuAJIHVQLwdrleYfszMAA= +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 h1:BlqrtbT9lLH3ZsOVhXPsHzFrApCTKRifB7gjJuypu6Y= +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/rcrowley/go-metrics v0.0.0-20190826022208-cac0b30c2563 h1:dY6ETXrvDG7Sa4vE8ZQG4yqWg6UnOcbqTAahkV813vQ= +github.com/prometheus/tsdb v0.10.0 h1:If5rVCMTp6W2SiRAQFlbpJNgVlgMEd+U2GZckwK38ic= +github.com/prometheus/tsdb v0.10.0/go.mod h1:oi49uRhEe9dPUTlS3JRZOwJuVi6tmh10QSgwXEyGCt4= +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/grpc-gateway/v2 v2.3.1-0.20210702154020-550e1cd83ec1 h1:xcu59yYL6AWWTl6jtejBfE0y8uF35fArCBeZjRlvJss= +github.com/prysmaticlabs/grpc-gateway/v2 v2.3.1-0.20210702154020-550e1cd83ec1/go.mod h1:IOyTYjcIO0rkmnGBfJTL0NJ11exy/Tc2QEuv7hCXp24= +github.com/prysmaticlabs/prombbolt v0.0.0-20210126082820-9b7adba6db7c h1:9PHRCuO/VN0s9k+RmLykho7AjDxblNYI5bYKed16NPU= +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 h1:+jhXLjEYVW4qU2z5SOxlxN+Hv/A9FDf0HpfDurfMEz0= +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/v3 v3.2.1 h1:K1cuIIh3tK/Z8943Xn1q1RU/4epnHcfwOJpNiue0Qcs= +github.com/prysmaticlabs/prysm/v3 v3.2.1/go.mod h1:W6h2+OurbfMNqWE2e3r+Uiit4plAW3W7ncDx1LIe8+I= +github.com/r3labs/sse v0.0.0-20210224172625-26fe804710bc h1:zAsgcP8MhzAbhMnB1QQ2O7ZhWYVGYSR2iVcjzQuPV+o= +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/retailnext/hllpp v1.0.1-0.20180308014038-101a6d2f8b52/go.mod h1:RDpi1RftBQPUCDRw6SmxeaREsAaRKnOclghuzp/WRzc= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.4.3 h1:utMvzDsuh3suAEnhH0RdHmoPbU648o6CvXxTx4SBMOw= +github.com/rivo/uniseg v0.4.3/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rjeczalik/notify v0.9.1 h1:CLCKso/QK1snAlnhNR/CNvNiFU2saUtjV0bx3EwNeCE= 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/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= +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.2 h1:KCooALfAYGs415Cwu5ABvv9n9509fSiG5SQJn/AQo4U= +github.com/rs/cors v1.8.2/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= +github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +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 h1:nMinx+JaEm/zJz4cEyClQeAw5rsYSB5th3xv+5lV6Vg= +github.com/schollz/progressbar/v3 v3.3.4/go.mod h1:Rp5lZwpgtYmlvmGo1FyDwXMqagyRBQYSDwzlP9QDu84= +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/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI= github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +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= +github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= +github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ= +github.com/shurcooL/gofontwoff v0.0.0-20180329035133-29b52fc0a18d/go.mod h1:05UtEgK5zq39gLST6uB0cf3NEHjETfB4Fgr3Gx5R9Vw= +github.com/shurcooL/gopherjslib v0.0.0-20160914041154-feb6d3990c2c/go.mod h1:8d3azKNyqcHP1GaQE/c6dDgjkgSx2BZ4IoEi4F1reUI= +github.com/shurcooL/highlight_diff v0.0.0-20170515013008-09bb4053de1b/go.mod h1:ZpfEhSmds4ytuByIcDnOLkTHGUI6KNqRNPDLHDk+mUU= +github.com/shurcooL/highlight_go v0.0.0-20181028180052-98c3abbbae20/go.mod h1:UDKB5a1T23gOMUJrI+uSuH0VRDStOiUVSjBTRDVBVag= +github.com/shurcooL/home v0.0.0-20181020052607-80b7ffcb30f9/go.mod h1:+rgNQw2P9ARFAs37qieuu7ohDNQ3gds9msbT2yn85sg= +github.com/shurcooL/htmlg v0.0.0-20170918183704-d01228ac9e50/go.mod h1:zPn1wHpTIePGnXSHpsVPWEktKXHr6+SS6x/IKRb7cpw= +github.com/shurcooL/httperror v0.0.0-20170206035902-86b7830d14cc/go.mod h1:aYMfkZ6DWSJPJ6c4Wwz3QtW22G7mf/PEgaB9k/ik5+Y= +github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= +github.com/shurcooL/httpgzip v0.0.0-20180522190206-b1c53ac65af9/go.mod h1:919LwcH0M7/W4fcZ0/jy0qGght1GIhqyS/EgWGH2j5Q= +github.com/shurcooL/issues v0.0.0-20181008053335-6292fdc1e191/go.mod h1:e2qWDig5bLteJ4fwvDAc2NHzqFEthkqn7aOZAOpj+PQ= +github.com/shurcooL/issuesapp v0.0.0-20180602232740-048589ce2241/go.mod h1:NPpHK2TI7iSaM0buivtFUc9offApnI0Alt/K8hcHy0I= +github.com/shurcooL/notifications v0.0.0-20181007000457-627ab5aea122/go.mod h1:b5uSkrEVM1jQUspwbixRBhaIjIzL2xazXp6kntxYle0= +github.com/shurcooL/octicon v0.0.0-20181028054416-fa4f57f9efb2/go.mod h1:eWdoE5JD4R5UVWDucdOPg1g2fqQRq78IQa9zlOV1vpQ= +github.com/shurcooL/reactions v0.0.0-20181006231557-f2e0b4ca5b82/go.mod h1:TCR1lToEk4d2s07G3XGfz2QrgHXg4RJBvjrOozvoWfk= +github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYEDaXHZDBsXlPCDqdhQuJkuw4NOtaxYe3xii4= +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/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 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU= +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.0.1-0.20201006035406-b97b5ead31f7/go.mod h1:yk5b0mALVusDL5fMM6Rd1wgnoO5jUPhwsQ6LQAJTidQ= +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/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4 h1:Gb2Tyox57NRNuZ2d3rmvB3pcmbu7O1RS3m8WRx7ilrg= +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/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= +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/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobtDnDzA= +github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg= +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= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 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= @@ -506,58 +1394,194 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= +github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= +github.com/supranational/blst v0.3.5/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= +github.com/supranational/blst v0.3.8-0.20220526154634-513d2456b344 h1:m+8fKfQwCAy1QjzINvKe/pYtLjo2dl59x2w9YSEJxuY= +github.com/supranational/blst v0.3.8-0.20220526154634-513d2456b344/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/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d/go.mod h1:RRCYJbIwD5jmqPI9XoAFR0OcDxqUctll6zUj/+B4S48= +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/tendermint/iavl v0.12.0 h1:xcaFAr+ycqCj7WN1RzL2EfcBioRDOHcU1oWcg83K028= github.com/tendermint/iavl v0.12.0/go.mod h1:EoKMMv++tDOL5qKKVnoIqtVPshRrEPeJ0WsgDOLAauM= +github.com/thomaso-mirodin/intmath v0.0.0-20160323211736-5dc6d854e46e h1:cR8/SYRgyQCt5cNCMniB/ZScMkhI9nk8U5C7SbISXjo= +github.com/thomaso-mirodin/intmath v0.0.0-20160323211736-5dc6d854e46e/go.mod h1:Tu4lItkATkonrYuvtVjG0/rhy15qrNGNTjPdaphtZ/8= +github.com/tidwall/gjson v1.10.2 h1:APbLGOM0rrEkd8WBw9C24nllro4ajFuJu0Sc9hRz8Bo= +github.com/tidwall/gjson v1.10.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= +github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= +github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= +github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/tidwall/tinylru v1.1.0 h1:XY6IUfzVTU9rpwdhKUF6nQdChgCdGjkMfLzbWyiau6I= +github.com/tidwall/tinylru v1.1.0/go.mod h1:3+bX+TJ2baOLMWTnlyNWHh4QMnFyARg2TLTQ6OFbzw8= +github.com/tidwall/wal v1.1.7 h1:emc1TRjIVsdKKSnpwGBAcsAGg0767SvUk8+ygx7Bb+4= +github.com/tidwall/wal v1.1.7/go.mod h1:r6lR1j27W9EPalgHiB7zLJDYu3mzW5BQP5KrzBpYY/E= github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= -github.com/tklauser/go-sysconf v0.3.5 h1:uu3Xl4nkLzQfXNsWn15rPc/HQCJKObbt1dKJeWp3vU4= +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/numcpus v0.2.2 h1:oyhllyrScuYI6g+h/zUvNXNp1wy7x8qQy3t/piefldA= +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/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef h1:wHSqTBrZW24CsNJDfeh9Ex6Pm0Rcpc7qrgKBiL44vF4= +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/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/trailofbits/go-mutexasserts v0.0.0-20200708152505-19999e7d3cef h1:8LRP+2JK8piIUU16ZDgWDXwjJcuJNTtCzadjTZj8Jf0= +github.com/trailofbits/go-mutexasserts v0.0.0-20200708152505-19999e7d3cef/go.mod h1:+SV/613m53DNAmlXPTWGZhIyt4E/qDvn9g/lOPRiy0A= +github.com/twitchtv/twirp v7.1.0+incompatible/go.mod h1:RRJoFSAmTEh2weEqWtpPE3vFK5YBhA6bqp2l1kfCC5A= 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 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= +github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= +github.com/uber/jaeger-client-go v2.25.0+incompatible h1:IxcNZ7WRY1Y3G4poYlx24szfsn/3LvK9QHCq9oQw8+U= +github.com/uber/jaeger-client-go v2.25.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= +github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +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.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= +github.com/urfave/cli/v2 v2.23.7 h1:YHDQ46s3VghFHFf1DdF+Sh7H4RqhcM+t0TmZRJx4oJY= +github.com/urfave/cli/v2 v2.23.7/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= 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/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 h1:ocEg3Ke2GkZ4vQw5lp46rmO+pfqCCTgq35gqOy8JKVc= +github.com/wealdtech/go-bytesutil v1.1.1/go.mod h1:jENeMqeTEU8FNZyDFRVc7KqBdRKSnJ9CCh26TcuNb9s= +github.com/wealdtech/go-eth2-types/v2 v2.5.2 h1:tiA6T88M6XQIbrV5Zz53l1G5HtRERcxQfmET225V4Ls= +github.com/wealdtech/go-eth2-types/v2 v2.5.2/go.mod h1:8lkNUbgklSQ4LZ2oMSuxSdR7WwJW3L9ge1dcoCVyzws= +github.com/wealdtech/go-eth2-util v1.6.3 h1:2INPeOR35x5LdFFpSzyw954WzTD+DFyHe3yKlJnG5As= +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 h1:SxrDVSr+oXuT1x8kZt4uWqNCvv5xXEGV9zd7cuSrZS8= +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 h1:264/meVYWt1wFw6Mtn+xwkZkXjID42gNra4rycoiDXI= +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 h1:lYbXeSvJi5zk5GLKVuid9TVjS9a0OmLIDKTfoZBL6Ow= +github.com/whyrusleeping/timecache v0.0.0-20160911033111-cfcb2f1abfee/go.mod h1:m2aV4LZI4Aez7dP5PMyVKEHhUyEJ/RjmPEDOpDvudHg= +github.com/willf/bitset v1.1.3 h1:ekJIKh6+YbUIVt9DfNbkR5d6aFcFTLDRyJNAACURBg8= github.com/willf/bitset v1.1.3/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/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/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.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +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.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ= go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= +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.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.6/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= +go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= +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.15.0 h1:vq3YWr8zRj1eFGC7Gvf907hE0eRjPTZ1d3xHadD6liE= +go.uber.org/dig v1.15.0/go.mod h1:pKHs0wMynzL6brANhB2hLMro+zalv1osARTviTcqHLM= +go.uber.org/fx v1.18.2 h1:bUNI6oShr+OVFQeU8cDNbnN7VFsu+SsjHzUF51V/GAU= +go.uber.org/fx v1.18.2/go.mod h1:g0V1KMQ66zIRk8bLu3Ea5Jt2w/cHlOIp4wdRsgh0JaY= +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.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8= +go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= +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= -golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +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.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= +go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= +golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw= 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-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-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-20211117183948-ae814b36b871/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE= golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -573,9 +1597,14 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 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-20230206171751-46f607a40771 h1:xP7rWLUr1e1n2xkK5YB4LI0hPEy3LJC6Wk+D4pGlOJg= +golang.org/x/exp v0.0.0-20230206171751-46f607a40771/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= @@ -586,6 +1615,7 @@ golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHl 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= @@ -595,15 +1625,26 @@ golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzB 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.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= +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/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 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= @@ -612,6 +1653,9 @@ golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLL 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= @@ -619,6 +1663,7 @@ golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLL 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= @@ -628,22 +1673,41 @@ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81R 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-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-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +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-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.5.0 h1:GyT4nK/YDHSqa1c4753ouYCDajOYKTja9Xb/OHtgvSw= -golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= +golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +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/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-20210427180440-81ed05c6b58c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.3.0 h1:6l90koy8/LaBLmLu8jpHeHexzMwEita0zFfYlggy2F8= +golang.org/x/oauth2 v0.3.0/go.mod h1:rQrIauxkUhJ6CuwEXwymO2/eh4xz2ZWF1nBkcxS+tGk= +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= @@ -657,70 +1721,118 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.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= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 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-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-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-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-20210806184541-e5e7981a1069/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-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-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18= -golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220405052023-b1e9470b6e64/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-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-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.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= +golang.org/x/sys v0.6.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.4.0 h1:O7UWfv5+A2qiuulQk30kVinPoMtoIPeVaKLEgLpVkvg= -golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= +golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +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= @@ -730,17 +1842,25 @@ 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.6.0 h1:3XmdazWV+ubf7QgHSTWeykHOci5oeekaGJBLkrkaw4k= -golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= +golang.org/x/text v0.8.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 h1:O8mE0/t419eoIwhTFpKVkHiTs/Igowgfkj25AcZrtiE= golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20220922220347-f3bd1da661af h1:Yx9k8YCG3dvF87UAn2tu2HQLf2dt/eR1bXxpLMWeH+Y= +golang.org/x/time v0.0.0-20220922220347-f3bd1da661af/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= @@ -757,6 +1877,10 @@ golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgw 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-20191112195655-aa38f8e97acc/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= @@ -764,6 +1888,7 @@ golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtn 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= @@ -771,6 +1896,7 @@ golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapK 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= @@ -779,26 +1905,39 @@ golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWc 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-20200522201501-cb1345f3a375/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-20200717024301-6ddee64345a6/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= 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.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +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.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= 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 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= 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= @@ -815,17 +1954,30 @@ google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0M 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 h1:k40adF3uR+6x/+hO5Dh4ZFUqFp67vxvbpafFiJxl10A= +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 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= +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= @@ -839,33 +1991,59 @@ google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvx 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-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 h1:PDIOdWxZ8eRizhKa1AAvY53xsvLB1cWorMjslvY3VA8= 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-20210207032614-bba0dbe2a9ea/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-20230110181048-76db0878b65f h1:BWUVssLB0HVOSY78gIdvk1dTVYtT1y8SBWtPYuTJ/6w= +google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +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= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +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.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.0 h1:T7P4R73V3SSDPhH7WW7ATbfViLtmamH0DKrP3f9AuDI= 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.35.0-dev.0.20201218190559-666aea1fb34c/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +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.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.52.0 h1:kd48UiU7EHsV4rnLyOJRuP/Il/UHE7gdDAQ+SZI7nZk= +google.golang.org/grpc v1.52.0/go.mod h1:pu6fVzoFb+NBYNAvQL08ic+lvB2IojljRYuun5vorUY= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.0.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= 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= @@ -876,24 +2054,49 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 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.25.1-0.20200805231151-a709e31e5d12/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.25.1-0.20201208041424-160c7477e0e8/go.mod h1:hFxJC2f0epmp1elRCiEGJTKAWbwxZ2nvqZdHl3FQXCY= 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.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= -google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.2-0.20220831092852-f930b1dc76e8 h1:KR8+MyP7/qOlV+8Af01LtjL04bu7on42eVsxT4EyBQk= +google.golang.org/protobuf v1.28.2-0.20220831092852-f930b1dc76e8/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 h1:Arh75ttbsvlpVA7WtVpH4u9h6Zl46xuptxqLxPiSo4Y= +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 h1:70AthpjunwzUiarMHyED52mj9UwtAnE89l1Gmrt3EU0= +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 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +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/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce h1:+JknDZhAj8YMt7GC73Ei8pv4MzjDUNPHgQWJdtMAaDU= 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 h1:NdAVW6RYxDif9DhDHaAortIu956m2c0v+09AZBPTbE0= 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= @@ -905,8 +2108,14 @@ gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +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 h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= +gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= +gotest.tools/v3 v3.2.0 h1:I0DwBVMGAx26dttAj1BtJLAkVGncrkkUXfJLC4Flt/I= +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= @@ -915,7 +2124,37 @@ honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt 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 h1:2AJaUQdgUZLoDZHrun21PW2Nx9+ll6cUzvn3IKhSIn0= +k8s.io/api v0.18.3/go.mod h1:UOaMwERbqJMfeeeHc8XJKawj4P9TgDRnViIqqBeH2QA= +k8s.io/apimachinery v0.18.3 h1:pOGcbVAhxADgUYnjS08EFXs9QMl8qaH5U4fr5LGUrSk= +k8s.io/apimachinery v0.18.3/go.mod h1:OaXp26zu/5J7p0f92ASynJa1pZo06YlV9fG7BoWbCko= +k8s.io/client-go v0.18.3 h1:QaJzz92tsN67oorwzmoB0a9r9ZVHuD5ryjbCKP0U22k= +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 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8= +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/klog/v2 v2.80.0 h1:lyJt0TWMPaGoODa8B8bUuxgHS3W/m/bNr2cca3brA/g= +k8s.io/klog/v2 v2.80.0/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +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 h1:ZtTUW5+ZWaoqjR3zOpRa7oFJ5d4aA22l4me/xArfOIc= +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= 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= +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 h1:dOmIZBMfhcHS09XZkMyUgkq5trg3/jRyJYFZUiaOp8E= +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 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q= +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/internal/ethapi/api.go b/internal/ethapi/api.go index 90744d4819..18f6746dca 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -2285,6 +2285,24 @@ func (s *PublicTransactionPoolAPI) SendRawTransaction(ctx context.Context, input return SubmitTransaction(ctx, s.b, tx) } +// SendRawTransactionConditional will add the signed transaction to the transaction pool. +// The sender/bundler is responsible for signing the transaction +func (s *PublicTransactionPoolAPI) SendRawTransactionConditional(ctx context.Context, input hexutil.Bytes, opts TransactionOpts) (common.Hash, error) { + tx := new(types.Transaction) + if err := tx.UnmarshalBinary(input); err != nil { + return common.Hash{}, err + } + header := s.b.CurrentHeader() + state, _, err := s.b.StateAndHeaderByNumber(ctx, rpc.BlockNumber(header.Number.Int64())) + if state == nil || err != nil { + return common.Hash{}, err + } + if err := opts.Check(header.Number.Uint64(), header.Time, state); err != nil { + return common.Hash{}, err + } + return SubmitTransaction(ctx, s.b, tx) +} + // Sign calculates an ECDSA signature for: // keccack256("\x19Ethereum Signed Message:\n" + len(message) + message). // diff --git a/internal/ethapi/backend.go b/internal/ethapi/backend.go index 9d6bca7f23..3360ff1879 100644 --- a/internal/ethapi/backend.go +++ b/internal/ethapi/backend.go @@ -93,6 +93,8 @@ type Backend interface { SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscription SubscribePendingLogsEvent(ch chan<- []*types.Log) event.Subscription SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent) event.Subscription + SubscribeNewVoteEvent(chan<- core.NewVoteEvent) event.Subscription + SubscribeFinalizedHeaderEvent(ch chan<- core.FinalizedHeaderEvent) event.Subscription ChainConfig() *params.ChainConfig Engine() consensus.Engine diff --git a/internal/ethapi/gen_tx_opts_json.go b/internal/ethapi/gen_tx_opts_json.go new file mode 100644 index 0000000000..19832cede1 --- /dev/null +++ b/internal/ethapi/gen_tx_opts_json.go @@ -0,0 +1,58 @@ +// Code generated by github.com/fjl/gencodec. DO NOT EDIT. + +package ethapi + +import ( + "encoding/json" + + "github.com/ethereum/go-ethereum/common/hexutil" +) + +// MarshalJSON marshals as JSON. +func (t TransactionOpts) MarshalJSON() ([]byte, error) { + type TransactionOpts struct { + KnownAccounts KnownAccounts `json:"knownAccounts"` + BlockNumberMin *hexutil.Uint64 `json:"blockNumberMin,omitempty"` + BlockNumberMax *hexutil.Uint64 `json:"blockNumberMax,omitempty"` + TimestampMin *hexutil.Uint64 `json:"timestampMin,omitempty"` + TimestampMax *hexutil.Uint64 `json:"timestampMax,omitempty"` + } + var enc TransactionOpts + enc.KnownAccounts = t.KnownAccounts + enc.BlockNumberMin = t.BlockNumberMin + enc.BlockNumberMax = t.BlockNumberMax + enc.TimestampMin = t.TimestampMin + enc.TimestampMax = t.TimestampMax + return json.Marshal(&enc) +} + +// UnmarshalJSON unmarshals from JSON. +func (t *TransactionOpts) UnmarshalJSON(input []byte) error { + type TransactionOpts struct { + KnownAccounts *KnownAccounts `json:"knownAccounts"` + BlockNumberMin *hexutil.Uint64 `json:"blockNumberMin,omitempty"` + BlockNumberMax *hexutil.Uint64 `json:"blockNumberMax,omitempty"` + TimestampMin *hexutil.Uint64 `json:"timestampMin,omitempty"` + TimestampMax *hexutil.Uint64 `json:"timestampMax,omitempty"` + } + var dec TransactionOpts + if err := json.Unmarshal(input, &dec); err != nil { + return err + } + if dec.KnownAccounts != nil { + t.KnownAccounts = *dec.KnownAccounts + } + if dec.BlockNumberMin != nil { + t.BlockNumberMin = dec.BlockNumberMin + } + if dec.BlockNumberMax != nil { + t.BlockNumberMax = dec.BlockNumberMax + } + if dec.TimestampMin != nil { + t.TimestampMin = dec.TimestampMin + } + if dec.TimestampMax != nil { + t.TimestampMax = dec.TimestampMax + } + return nil +} diff --git a/internal/ethapi/transaction_options.go b/internal/ethapi/transaction_options.go new file mode 100644 index 0000000000..77b1729037 --- /dev/null +++ b/internal/ethapi/transaction_options.go @@ -0,0 +1,94 @@ +package ethapi + +import ( + "bytes" + "encoding/json" + "errors" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core/state" +) + +type AccountStorage struct { + StorageRoot *common.Hash + StorageSlots map[common.Hash]common.Hash +} + +func (a *AccountStorage) UnmarshalJSON(data []byte) error { + var hash common.Hash + if err := json.Unmarshal(data, &hash); err == nil { + a.StorageRoot = &hash + return nil + } + return json.Unmarshal(data, &a.StorageSlots) +} + +func (a AccountStorage) MarshalJSON() ([]byte, error) { + if a.StorageRoot != nil { + return json.Marshal(*a.StorageRoot) + } + return json.Marshal(a.StorageSlots) +} + +type KnownAccounts map[common.Address]AccountStorage + +// It is known that marshaling is broken +// https://github.com/golang/go/issues/55890 + +//go:generate go run github.com/fjl/gencodec -type TransactionOpts -out gen_tx_opts_json.go +type TransactionOpts struct { + KnownAccounts KnownAccounts `json:"knownAccounts"` + BlockNumberMin *hexutil.Uint64 `json:"blockNumberMin,omitempty"` + BlockNumberMax *hexutil.Uint64 `json:"blockNumberMax,omitempty"` + TimestampMin *hexutil.Uint64 `json:"timestampMin,omitempty"` + TimestampMax *hexutil.Uint64 `json:"timestampMax,omitempty"` +} + +const MaxNumberOfEntries = 1000 + +func (o *TransactionOpts) Check(blockNumber uint64, timeStamp uint64, statedb *state.StateDB) error { + if o.BlockNumberMin != nil && blockNumber < uint64(*o.BlockNumberMin) { + return errors.New("BlockNumberMin condition not met") + } + if o.BlockNumberMax != nil && blockNumber > uint64(*o.BlockNumberMax) { + return errors.New("BlockNumberMax condition not met") + } + if o.TimestampMin != nil && timeStamp < uint64(*o.TimestampMin) { + return errors.New("TimestampMin condition not met") + } + if o.TimestampMax != nil && timeStamp > uint64(*o.TimestampMax) { + return errors.New("TimestampMax condition not met") + } + counter := 0 + for _, account := range o.KnownAccounts { + if account.StorageRoot != nil { + counter += 1 + } else if account.StorageSlots != nil { + counter += len(account.StorageSlots) + } + } + if counter > MaxNumberOfEntries { + return errors.New("knownAccounts too large") + } + return o.CheckStorage(statedb) +} + +func (o *TransactionOpts) CheckStorage(statedb *state.StateDB) error { + for address, accountStorage := range o.KnownAccounts { + if accountStorage.StorageRoot != nil { + rootHash := statedb.GetRoot(address) + if rootHash != *accountStorage.StorageRoot { + return errors.New("storage root hash condition not met") + } + } else if len(accountStorage.StorageSlots) > 0 { + for slot, value := range accountStorage.StorageSlots { + stored := statedb.GetState(address, slot) + if !bytes.Equal(stored.Bytes(), value.Bytes()) { + return errors.New("storage slot value condition not met") + } + } + } + } + return nil +} diff --git a/internal/ethapi/transaction_options_test.go b/internal/ethapi/transaction_options_test.go new file mode 100644 index 0000000000..479f46a145 --- /dev/null +++ b/internal/ethapi/transaction_options_test.go @@ -0,0 +1,122 @@ +package ethapi_test + +import ( + "encoding/json" + "reflect" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/internal/ethapi" +) + +func ptr(hash common.Hash) *common.Hash { + return &hash +} + +func u64Ptr(v hexutil.Uint64) *hexutil.Uint64 { + return &v +} + +func TestTransactionOptsJSONUnMarshalTrip(t *testing.T) { + tests := []struct { + name string + input string + mustFail bool + expected ethapi.TransactionOpts + }{ + { + "StateRoot", + `{"knownAccounts":{"0x6b3A8798E5Fb9fC5603F3aB5eA2e8136694e55d0":"0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563"}}`, + false, + ethapi.TransactionOpts{ + KnownAccounts: map[common.Address]ethapi.AccountStorage{ + common.HexToAddress("0x6b3A8798E5Fb9fC5603F3aB5eA2e8136694e55d0"): ethapi.AccountStorage{ + StorageRoot: ptr(common.HexToHash("0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563")), + }, + }, + }, + }, + { + "StorageSlots", + `{"knownAccounts":{"0x6b3A8798E5Fb9fC5603F3aB5eA2e8136694e55d0":{"0xc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a8":"0x0000000000000000000000000000000000000000000000000000000000000000"}}}`, + false, + ethapi.TransactionOpts{ + KnownAccounts: map[common.Address]ethapi.AccountStorage{ + common.HexToAddress("0x6b3A8798E5Fb9fC5603F3aB5eA2e8136694e55d0"): ethapi.AccountStorage{ + StorageRoot: nil, + StorageSlots: map[common.Hash]common.Hash{ + common.HexToHash("0xc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a8"): common.HexToHash("0x"), + }, + }, + }, + }, + }, + { + "EmptyObject", + `{"knownAccounts":{}}`, + false, + ethapi.TransactionOpts{ + KnownAccounts: make(map[common.Address]ethapi.AccountStorage), + }, + }, + { + "EmptyStrings", + `{"knownAccounts":{"":""}}`, + true, + ethapi.TransactionOpts{ + KnownAccounts: nil, + }, + }, + { + "BlockNumberMin", + `{"blockNumberMin":"0x1"}`, + false, + ethapi.TransactionOpts{ + BlockNumberMin: u64Ptr(1), + }, + }, + { + "BlockNumberMax", + `{"blockNumberMin":"0x1", "blockNumberMax":"0x2"}`, + false, + ethapi.TransactionOpts{ + BlockNumberMin: u64Ptr(1), + BlockNumberMax: u64Ptr(2), + }, + }, + { + "TimestampMin", + `{"timestampMin":"0xffff"}`, + false, + ethapi.TransactionOpts{ + TimestampMin: u64Ptr(0xffff), + }, + }, + { + "TimestampMax", + `{"timestampMax":"0xffffff"}`, + false, + ethapi.TransactionOpts{ + TimestampMax: u64Ptr(0xffffff), + }, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + var opts ethapi.TransactionOpts + err := json.Unmarshal([]byte(test.input), &opts) + if test.mustFail && err == nil { + t.Errorf("Test %s should fail", test.name) + } + if !test.mustFail && err != nil { + t.Errorf("Test %s should pass but got err: %v", test.name, err) + } + + if !reflect.DeepEqual(opts, test.expected) { + t.Errorf("Test %s got unexpected value, want %#v, got %#v", test.name, test.expected, opts) + } + }) + } +} diff --git a/internal/jsre/deps/web3.js b/internal/jsre/deps/web3.js index 5d27887474..02650a68f3 100644 --- a/internal/jsre/deps/web3.js +++ b/internal/jsre/deps/web3.js @@ -5438,6 +5438,13 @@ var methods = function () { inputFormatter: [null] }); + var sendRawTransactionConditional = new Method({ + name: 'sendRawTransactionConditional', + call: 'eth_sendRawTransactionConditional', + params: 2, + inputFormatter: [null] + }); + var sendTransaction = new Method({ name: 'sendTransaction', call: 'eth_sendTransaction', @@ -5523,6 +5530,7 @@ var methods = function () { call, estimateGas, sendRawTransaction, + sendRawTransactionConditional, signTransaction, sendTransaction, sign, diff --git a/les/api_backend.go b/les/api_backend.go index 0e02a03050..e354b19fe6 100644 --- a/les/api_backend.go +++ b/les/api_backend.go @@ -36,6 +36,7 @@ import ( "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/light" + "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rpc" ) @@ -231,6 +232,11 @@ func (b *LesApiBackend) SubscribeNewTxsEvent(ch chan<- core.NewTxsEvent) event.S return b.eth.txPool.SubscribeNewTxsEvent(ch) } +func (b *LesApiBackend) SubscribeNewVoteEvent(ch chan<- core.NewVoteEvent) event.Subscription { + log.Error("light ethereum does not support SubscribeNewVoteEvent") + return nil +} + func (b *LesApiBackend) SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription { return b.eth.blockchain.SubscribeChainEvent(ch) } @@ -239,6 +245,10 @@ func (b *LesApiBackend) SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) e return b.eth.blockchain.SubscribeChainHeadEvent(ch) } +func (b *LesApiBackend) SubscribeFinalizedHeaderEvent(ch chan<- core.FinalizedHeaderEvent) event.Subscription { + return b.eth.blockchain.SubscribeFinalizedHeaderEvent(ch) +} + func (b *LesApiBackend) SubscribeChainSideEvent(ch chan<- core.ChainSideEvent) event.Subscription { return b.eth.blockchain.SubscribeChainSideEvent(ch) } diff --git a/light/lightchain.go b/light/lightchain.go index 7ce0b2698d..086b673d30 100644 --- a/light/lightchain.go +++ b/light/lightchain.go @@ -50,17 +50,18 @@ var ( // headers, downloading block bodies and receipts on demand through an ODR // interface. It only does header validation during chain insertion. type LightChain struct { - hc *core.HeaderChain - indexerConfig *IndexerConfig - chainDb ethdb.Database - engine consensus.Engine - odr OdrBackend - chainFeed event.Feed - chainSideFeed event.Feed - chainHeadFeed event.Feed - scope event.SubscriptionScope - genesisBlock *types.Block - forker *core.ForkChoice + hc *core.HeaderChain + indexerConfig *IndexerConfig + chainDb ethdb.Database + engine consensus.Engine + odr OdrBackend + chainFeed event.Feed + chainSideFeed event.Feed + chainHeadFeed event.Feed + finalizedHeaderFeed event.Feed + scope event.SubscriptionScope + genesisBlock *types.Block + forker *core.ForkChoice bodyCache *lru.Cache // Cache for the most recent block bodies bodyRLPCache *lru.Cache // Cache for the most recent block bodies in RLP encoded format @@ -370,6 +371,8 @@ func (lc *LightChain) postChainEvents(events []interface{}) { lc.chainHeadFeed.Send(core.ChainHeadEvent{Block: ev.Block}) } lc.chainFeed.Send(ev) + case core.FinalizedHeaderEvent: + lc.finalizedHeaderFeed.Send(ev) case core.ChainSideEvent: lc.chainSideFeed.Send(ev) } @@ -456,6 +459,9 @@ func (lc *LightChain) InsertHeaderChain(chain []*types.Header, checkFreq int) (i case core.CanonStatTy: lc.chainFeed.Send(core.ChainEvent{Block: block, Hash: block.Hash()}) lc.chainHeadFeed.Send(core.ChainHeadEvent{Block: block}) + if posa, ok := lc.Engine().(consensus.PoSA); ok { + lc.finalizedHeaderFeed.Send(core.FinalizedHeaderEvent{Header: posa.GetFinalizedHeader(lc, block.Header())}) + } case core.SideStatTy: lc.chainSideFeed.Send(core.ChainSideEvent{Block: block}) } @@ -468,6 +474,19 @@ func (lc *LightChain) CurrentHeader() *types.Header { return lc.hc.CurrentHeader() } +// GetJustifiedNumber returns the highest justified blockNumber on the branch including and before `header` +func (lc *LightChain) GetJustifiedNumber(header *types.Header) uint64 { + if p, ok := lc.engine.(consensus.PoSA); ok { + justifiedBlockNumber, _, err := p.GetJustifiedNumberAndHash(lc.hc, header) + if err == nil { + return justifiedBlockNumber + } + } + // return 0 when err!=nil + // so the input `header` will at a disadvantage during reorg + return 0 +} + // GetTd retrieves a block's total difficulty in the canonical chain from the // database by hash and number, caching it if found. func (lc *LightChain) GetTd(hash common.Hash, number uint64) *big.Int { @@ -588,6 +607,11 @@ func (lc *LightChain) SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) eve return lc.scope.Track(lc.chainHeadFeed.Subscribe(ch)) } +// SubscribeFinalizedHeaderEvent registers a subscription of FinalizedHeaderEvent. +func (lc *LightChain) SubscribeFinalizedHeaderEvent(ch chan<- core.FinalizedHeaderEvent) event.Subscription { + return lc.scope.Track(lc.finalizedHeaderFeed.Subscribe(ch)) +} + // SubscribeChainSideEvent registers a subscription of ChainSideEvent. func (lc *LightChain) SubscribeChainSideEvent(ch chan<- core.ChainSideEvent) event.Subscription { return lc.scope.Track(lc.chainSideFeed.Subscribe(ch)) diff --git a/log/format.go b/log/format.go index 613dc33be7..6c1d5942b3 100644 --- a/log/format.go +++ b/log/format.go @@ -14,9 +14,12 @@ import ( "unicode/utf8" ) +var ( + timeFormat = "2006-01-02T15:04:05-0700" + termTimeFormat = "01-02|15:04:05.000" +) + const ( - timeFormat = "2006-01-02T15:04:05-0700" - termTimeFormat = "01-02|15:04:05.000" floatFormat = 'f' termMsgJust = 40 termCtxMaxPadding = 40 @@ -482,3 +485,11 @@ func escapeString(s string) string { } return strconv.Quote(s) } + +func SetTermTimeFormat(format string) { + termTimeFormat = format +} + +func SetTimeFormat(format string) { + timeFormat = format +} diff --git a/miner/miner.go b/miner/miner.go index 7f0f1583e8..de575ee69c 100644 --- a/miner/miner.go +++ b/miner/miner.go @@ -54,6 +54,7 @@ type Config struct { GasPrice *big.Int // Minimum gas price for mining a transaction Recommit time.Duration // The time interval for miner to re-create mining work. Noverify bool // Disable remote mining solution verification(only useful in ethash). + VoteEnable bool // whether enable voting } // Miner creates blocks and searches for proof-of-work values. diff --git a/miner/worker.go b/miner/worker.go index 37f458693e..9f4cce2988 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -666,20 +666,23 @@ func (w *worker) resultLoop() { w.recentMinedBlocks.Add(block.NumberU64(), []common.Hash{block.ParentHash()}) } - // Broadcast the block and announce chain insertion event - w.mux.Post(core.NewMinedBlockEvent{Block: block}) - // Commit block and state to database. task.state.SetExpectedStateRoot(block.Root()) start := time.Now() - _, err := w.chain.WriteBlockAndSetHead(block, receipts, logs, task.state, true) - if err != nil { - log.Error("Failed writing block to chain", "err", err) + status, err := w.chain.WriteBlockAndSetHead(block, receipts, logs, task.state, true) + if status != core.CanonStatTy { + if err != nil { + log.Error("Failed writing block to chain", "err", err, "status", status) + } else { + log.Info("Written block as SideChain and avoid broadcasting", "status", status) + } continue } writeBlockTimer.UpdateSince(start) log.Info("Successfully sealed new block", "number", block.Number(), "sealhash", sealhash, "hash", hash, "elapsed", common.PrettyDuration(time.Since(task.createdAt))) + // Broadcast the block and announce chain insertion event + w.mux.Post(core.NewMinedBlockEvent{Block: block}) // Insert the block into the set of pending ones to resultLoop for confirmations w.unconfirmed.Insert(block.NumberU64(), block.Hash()) diff --git a/mobile/ethclient.go b/mobile/ethclient.go index 662125c4ad..59e39e53ec 100644 --- a/mobile/ethclient.go +++ b/mobile/ethclient.go @@ -148,6 +148,74 @@ func (ec *EthereumClient) SubscribeNewHead(ctx *Context, handler NewHeadHandler, return &Subscription{rawSub}, nil } +// NewFinalizedHeaderHandler is a client-side subscription callback to invoke on events and +// subscription failure. +type NewFinalizedHeaderHandler interface { + OnNewFinalizedHeader(header *Header) + OnError(failure string) +} + +// SubscribeNewFinalizedHeader subscribes to notifications about the current blockchain finalized header +// on the given channel. +func (ec *EthereumClient) SubscribeNewFinalizedHeader(ctx *Context, handler NewFinalizedHeaderHandler, buffer int) (sub *Subscription, _ error) { + // Subscribe to the event internally + ch := make(chan *types.Header, buffer) + rawSub, err := ec.client.SubscribeNewFinalizedHeader(ctx.context, ch) + if err != nil { + return nil, err + } + // Start up a dispatcher to feed into the callback + go func() { + for { + select { + case header := <-ch: + handler.OnNewFinalizedHeader(&Header{header}) + + case err := <-rawSub.Err(): + if err != nil { + handler.OnError(err.Error()) + } + return + } + } + }() + return &Subscription{rawSub}, nil +} + +// NewVoteHandler is a client-side subscription callback to invoke on events and +// subscription failure. +type NewVoteHandler interface { + OnNewVote(vote *types.VoteEnvelope) + OnError(failure string) +} + +// SubscribeNewVotes subscribes to notifications about the new votes into the vote pool +// on the given channel. +func (ec *EthereumClient) SubscribeNewVotes(ctx *Context, handler NewVoteHandler, buffer int) (sub *Subscription, _ error) { + // Subscribe to the event internally + ch := make(chan *types.VoteEnvelope, buffer) + rawSub, err := ec.client.SubscribeNewVotes(ctx.context, ch) + if err != nil { + return nil, err + } + // Start up a dispatcher to feed into the callback + go func() { + for { + select { + case vote := <-ch: + handler.OnNewVote(vote) + + case err := <-rawSub.Err(): + if err != nil { + handler.OnError(err.Error()) + } + return + } + } + }() + return &Subscription{rawSub}, nil +} + // State Access // GetBalanceAt returns the wei balance of the given account. diff --git a/node/config.go b/node/config.go index 2e37c23532..cd87e26362 100644 --- a/node/config.go +++ b/node/config.go @@ -204,6 +204,17 @@ type Config struct { // EnableDoubleSignMonitor is a flag that whether to enable the double signature checker EnableDoubleSignMonitor bool `toml:",omitempty"` + + // BLSPasswordFile is the file that contains BLS wallet password. + BLSPasswordFile string `toml:",omitempty"` + + // BLSWalletDir is the file system folder of BLS wallet. The directory can + // be specified as a relative path, in which case it is resolved relative to the + // current directory. + BLSWalletDir string `toml:",omitempty"` + + // VoteJournalDir is the directory to store votes in the fast finality feature. + VoteJournalDir string `toml:",omitempty"` } // IPCEndpoint resolves an IPC endpoint based on a configured value, taking into @@ -502,8 +513,13 @@ func (c *Config) warnOnce(w *bool, format string, args ...interface{}) { } type LogConfig struct { - FileRoot string - FilePath string - MaxBytesSize uint - Level string + FileRoot *string `toml:",omitempty"` + FilePath *string `toml:",omitempty"` + MaxBytesSize *uint `toml:",omitempty"` + Level *string `toml:",omitempty"` + + // TermTimeFormat is the time format used for console logging. + TermTimeFormat *string `toml:",omitempty"` + // TimeFormat is the time format used for file logging. + TimeFormat *string `toml:",omitempty"` } diff --git a/node/node.go b/node/node.go index 48f7b4c4be..ef256f77e7 100644 --- a/node/node.go +++ b/node/node.go @@ -86,13 +86,25 @@ func New(conf *Config) (*Node, error) { conf.DataDir = absdatadir } if conf.LogConfig != nil { - logFilePath := "" - if conf.LogConfig.FileRoot == "" { - logFilePath = path.Join(conf.DataDir, conf.LogConfig.FilePath) - } else { - logFilePath = path.Join(conf.LogConfig.FileRoot, conf.LogConfig.FilePath) + if conf.LogConfig.TermTimeFormat != nil && *conf.LogConfig.TermTimeFormat != "" { + log.SetTermTimeFormat(*conf.LogConfig.TermTimeFormat) + } + + if conf.LogConfig.TimeFormat != nil && *conf.LogConfig.TimeFormat != "" { + log.SetTimeFormat(*conf.LogConfig.TimeFormat) + } + + if conf.LogConfig.FileRoot != nil && conf.LogConfig.FilePath != nil && + conf.LogConfig.MaxBytesSize != nil && conf.LogConfig.Level != nil { + // log to file + logFilePath := "" + if *conf.LogConfig.FileRoot == "" { + logFilePath = path.Join(conf.DataDir, *conf.LogConfig.FilePath) + } else { + logFilePath = path.Join(*conf.LogConfig.FileRoot, *conf.LogConfig.FilePath) + } + log.Root().SetHandler(log.NewFileLvlHandler(logFilePath, *conf.LogConfig.MaxBytesSize, *conf.LogConfig.Level)) } - log.Root().SetHandler(log.NewFileLvlHandler(logFilePath, conf.LogConfig.MaxBytesSize, conf.LogConfig.Level)) } if conf.Logger == nil { conf.Logger = log.New() diff --git a/p2p/discover/v5_udp.go b/p2p/discover/v5_udp.go index 1e9909559f..f98b8eadd9 100644 --- a/p2p/discover/v5_udp.go +++ b/p2p/discover/v5_udp.go @@ -54,7 +54,7 @@ type codecV5 interface { // Encode encodes a packet. Encode(enode.ID, string, v5wire.Packet, *v5wire.Whoareyou) ([]byte, v5wire.Nonce, error) - // decode decodes a packet. It returns a *v5wire.Unknown packet if decryption fails. + // Decode decodes a packet. It returns a *v5wire.Unknown packet if decryption fails. // The *enode.Node return value is non-nil when the input contains a handshake response. Decode([]byte, string) (enode.ID, *enode.Node, v5wire.Packet, error) } diff --git a/p2p/transport.go b/p2p/transport.go index de9e685ed4..f71fce070c 100644 --- a/p2p/transport.go +++ b/p2p/transport.go @@ -136,7 +136,7 @@ func (t *rlpxTransport) doProtoHandshake(our *protoHandshake) (their *protoHands // Writing our handshake happens concurrently, we prefer // returning the handshake read error. If the remote side // disconnects us early with a valid reason, we should return it - // as the error so it can be tracked elsewhere. + // as the error, so it can be tracked elsewhere. werr := make(chan error, 1) gopool.Submit(func() { werr <- Send(t, handshakeMsg, our) }) if their, err = readProtocolHandshake(t); err != nil { diff --git a/params/config.go b/params/config.go index f4c485f227..da7f40128c 100644 --- a/params/config.go +++ b/params/config.go @@ -74,6 +74,80 @@ var ( Ethash: new(EthashConfig), } + // just for prysm compile pass + // RopstenChainConfig contains the chain parameters to run a node on the Ropsten test network. + RopstenChainConfig = &ChainConfig{ + ChainID: big.NewInt(3), + HomesteadBlock: big.NewInt(0), + DAOForkBlock: nil, + DAOForkSupport: true, + EIP150Block: big.NewInt(0), + EIP150Hash: common.HexToHash("0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d"), + EIP155Block: big.NewInt(10), + EIP158Block: big.NewInt(10), + ByzantiumBlock: big.NewInt(1_700_000), + ConstantinopleBlock: big.NewInt(4_230_000), + PetersburgBlock: big.NewInt(4_939_394), + IstanbulBlock: big.NewInt(6_485_846), + MuirGlacierBlock: big.NewInt(7_117_117), + BerlinBlock: big.NewInt(9_812_189), + LondonBlock: big.NewInt(10_499_401), + TerminalTotalDifficulty: new(big.Int).SetUint64(50_000_000_000_000_000), + Ethash: new(EthashConfig), + } + + // just for prysm compile pass + // SepoliaChainConfig contains the chain parameters to run a node on the Sepolia test network. + SepoliaChainConfig = &ChainConfig{ + ChainID: big.NewInt(11155111), + HomesteadBlock: big.NewInt(0), + DAOForkBlock: nil, + DAOForkSupport: true, + EIP150Block: big.NewInt(0), + EIP155Block: big.NewInt(0), + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + IstanbulBlock: big.NewInt(0), + MuirGlacierBlock: big.NewInt(0), + BerlinBlock: big.NewInt(0), + MirrorSyncBlock: big.NewInt(0), + BrunoBlock: big.NewInt(0), + EulerBlock: big.NewInt(0), + LondonBlock: big.NewInt(0), + Ethash: new(EthashConfig), + } + + // just for prysm compile pass + // GoerliChainConfig contains the chain parameters to run a node on the Görli test network. + GoerliChainConfig = &ChainConfig{ + ChainID: big.NewInt(5), + HomesteadBlock: big.NewInt(0), + DAOForkBlock: nil, + DAOForkSupport: true, + EIP150Block: big.NewInt(0), + EIP155Block: big.NewInt(0), + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + RamanujanBlock: big.NewInt(0), + NielsBlock: big.NewInt(0), + MirrorSyncBlock: big.NewInt(0), + BrunoBlock: big.NewInt(0), + EulerBlock: big.NewInt(0), + IstanbulBlock: big.NewInt(1_561_651), + MuirGlacierBlock: nil, + BerlinBlock: big.NewInt(4_460_644), + LondonBlock: big.NewInt(5_062_605), + ArrowGlacierBlock: nil, + Clique: &CliqueConfig{ + Period: 15, + Epoch: 30000, + }, + } + // MainnetTrustedCheckpoint contains the light client trusted checkpoint for the main network. MainnetTrustedCheckpoint = &TrustedCheckpoint{ SectionIndex: 413, @@ -116,6 +190,11 @@ var ( GibbsBlock: big.NewInt(23846001), PlanckBlock: big.NewInt(27281024), + // TODO modify blockNumber, make sure the blockNumber is not an integer multiple of 200 (epoch number) + // TODO Caution !!! it should be very careful !!! + LubanBlock: nil, + PlatoBlock: nil, + Parlia: &ParliaConfig{ Period: 3, Epoch: 200, @@ -142,6 +221,12 @@ var ( NanoBlock: big.NewInt(23482428), MoranBlock: big.NewInt(23603940), PlanckBlock: big.NewInt(28196022), + + // TODO modify blockNumber, make sure the blockNumber is not an integer multiple of 200 (epoch number) + // TODO Caution !!! it should be very careful !!! + LubanBlock: big.NewInt(29295050), + PlatoBlock: nil, + Parlia: &ParliaConfig{ Period: 3, Epoch: 200, @@ -169,6 +254,10 @@ var ( MoranBlock: nil, PlanckBlock: nil, + // TODO + LubanBlock: nil, + PlatoBlock: nil, + Parlia: &ParliaConfig{ Period: 3, Epoch: 200, @@ -180,16 +269,17 @@ var ( // // This configuration is intentionally not using keyed fields to force anyone // adding flags to the config to also have to set these fields. - AllEthashProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), new(EthashConfig), nil, nil} + + AllEthashProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), new(EthashConfig), nil, nil} // AllCliqueProtocolChanges contains every protocol change (EIPs) introduced // and accepted by the Ethereum core developers into the Clique consensus. // // This configuration is intentionally not using keyed fields to force anyone // adding flags to the config to also have to set these fields. - AllCliqueProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, big.NewInt(0), nil, nil, nil, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, nil, &CliqueConfig{Period: 0, Epoch: 30000}, nil} + AllCliqueProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, big.NewInt(0), nil, nil, nil, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, big.NewInt(0), big.NewInt(0), nil, &CliqueConfig{Period: 0, Epoch: 30000}, nil} - TestChainConfig = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, new(EthashConfig), nil, nil} + TestChainConfig = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, big.NewInt(0), big.NewInt(0), new(EthashConfig), nil, nil} TestRules = TestChainConfig.Rules(new(big.Int), false) ) @@ -286,6 +376,8 @@ type ChainConfig struct { NanoBlock *big.Int `json:"nanoBlock,omitempty" toml:",omitempty"` // nanoBlock switch block (nil = no fork, 0 = already activated) MoranBlock *big.Int `json:"moranBlock,omitempty" toml:",omitempty"` // moranBlock switch block (nil = no fork, 0 = already activated) PlanckBlock *big.Int `json:"planckBlock,omitempty" toml:",omitempty"` // planckBlock switch block (nil = no fork, 0 = already activated) + LubanBlock *big.Int `json:"lubanBlock,omitempty" toml:",omitempty"` // lubanBlock switch block (nil = no fork, 0 = already activated) + PlatoBlock *big.Int `json:"platoBlock,omitempty" toml:",omitempty"` // platoBlock switch block (nil = no fork, 0 = already activated) // Various consensus engines Ethash *EthashConfig `json:"ethash,omitempty" toml:",omitempty"` @@ -336,7 +428,8 @@ func (c *ChainConfig) String() string { default: engine = "unknown" } - return fmt.Sprintf("{ChainID: %v Homestead: %v DAO: %v DAOSupport: %v EIP150: %v EIP155: %v EIP158: %v Byzantium: %v Constantinople: %v Petersburg: %v Istanbul: %v, Muir Glacier: %v, Ramanujan: %v, Niels: %v, MirrorSync: %v, Bruno: %v, Berlin: %v, YOLO v3: %v, CatalystBlock: %v, London: %v, ArrowGlacier: %v, MergeFork:%v, Euler: %v, Gibbs: %v, Nano: %v, Moran: %v, Planck: %v, Engine: %v}", + + return fmt.Sprintf("{ChainID: %v Homestead: %v DAO: %v DAOSupport: %v EIP150: %v EIP155: %v EIP158: %v Byzantium: %v Constantinople: %v Petersburg: %v Istanbul: %v, Muir Glacier: %v, Ramanujan: %v, Niels: %v, MirrorSync: %v, Bruno: %v, Berlin: %v, YOLO v3: %v, CatalystBlock: %v, London: %v, ArrowGlacier: %v, MergeFork:%v, Euler: %v, Gibbs: %v, Nano: %v, Moran: %v, Planck: %v,Luban: %v, Plato: %v, Engine: %v}", c.ChainID, c.HomesteadBlock, c.DAOForkBlock, @@ -364,6 +457,8 @@ func (c *ChainConfig) String() string { c.NanoBlock, c.MoranBlock, c.PlanckBlock, + c.LubanBlock, + c.PlatoBlock, engine, ) } @@ -453,6 +548,26 @@ func (c *ChainConfig) IsOnEuler(num *big.Int) bool { return configNumEqual(c.EulerBlock, num) } +// IsLuban returns whether num is either equal to the first fast finality fork block or greater. +func (c *ChainConfig) IsLuban(num *big.Int) bool { + return isForked(c.LubanBlock, num) +} + +// IsOnLuban returns whether num is equal to the first fast finality fork block. +func (c *ChainConfig) IsOnLuban(num *big.Int) bool { + return configNumEqual(c.LubanBlock, num) +} + +// IsPlato returns whether num is either equal to the second fast finality fork block or greater. +func (c *ChainConfig) IsPlato(num *big.Int) bool { + return isForked(c.PlatoBlock, num) +} + +// IsOnPlato returns whether num is equal to the second fast finality fork block. +func (c *ChainConfig) IsOnPlato(num *big.Int) bool { + return configNumEqual(c.PlatoBlock, num) +} + // IsMuirGlacier returns whether num is either equal to the Muir Glacier (EIP-2384) fork block or greater. func (c *ChainConfig) IsMuirGlacier(num *big.Int) bool { return isForked(c.MuirGlacierBlock, num) @@ -559,6 +674,8 @@ func (c *ChainConfig) CheckConfigForkOrder() error { {name: "brunoBlock", block: c.BrunoBlock}, {name: "eulerBlock", block: c.EulerBlock}, {name: "gibbsBlock", block: c.GibbsBlock}, + {name: "lubanBlock", block: c.LubanBlock}, + {name: "platoBlock", block: c.PlatoBlock}, } { if lastFork.name != "" { // Next one must be higher number @@ -658,6 +775,12 @@ func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, head *big.Int) *Confi if isForkIncompatible(c.PlanckBlock, newcfg.PlanckBlock, head) { return newCompatError("planck fork block", c.PlanckBlock, newcfg.PlanckBlock) } + if isForkIncompatible(c.LubanBlock, newcfg.LubanBlock, head) { + return newCompatError("luban fork block", c.LubanBlock, newcfg.LubanBlock) + } + if isForkIncompatible(c.PlatoBlock, newcfg.PlatoBlock, head) { + return newCompatError("plato fork block", c.PlatoBlock, newcfg.PlatoBlock) + } return nil } @@ -730,6 +853,7 @@ type Rules struct { IsNano bool IsMoran bool IsPlanck bool + IsLuban bool } // Rules ensures c's ChainID is not nil. @@ -754,5 +878,6 @@ func (c *ChainConfig) Rules(num *big.Int, isMerge bool) Rules { IsNano: c.IsNano(num), IsMoran: c.IsMoran(num), IsPlanck: c.IsPlanck(num), + IsLuban: c.IsLuban(num), } } diff --git a/params/protocol_params.go b/params/protocol_params.go index e244c24231..527c6dc166 100644 --- a/params/protocol_params.go +++ b/params/protocol_params.go @@ -129,16 +129,19 @@ const ( // Precompiled contract gas prices - TendermintHeaderValidateGas uint64 = 3000 // Gas for validate tendermiint consensus state - IAVLMerkleProofValidateGas uint64 = 3000 // Gas for validate merkle proof - - EcrecoverGas uint64 = 3000 // Elliptic curve sender recovery gas price - Sha256BaseGas uint64 = 60 // Base price for a SHA256 operation - Sha256PerWordGas uint64 = 12 // Per-word price for a SHA256 operation - Ripemd160BaseGas uint64 = 600 // Base price for a RIPEMD160 operation - Ripemd160PerWordGas uint64 = 120 // Per-word price for a RIPEMD160 operation - IdentityBaseGas uint64 = 15 // Base price for a data copy operation - IdentityPerWordGas uint64 = 3 // Per-work price for a data copy operation + 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 + Sha256PerWordGas uint64 = 12 // Per-word price for a SHA256 operation + Ripemd160BaseGas uint64 = 600 // Base price for a RIPEMD160 operation + Ripemd160PerWordGas uint64 = 120 // Per-word price for a RIPEMD160 operation + 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 diff --git a/params/version.go b/params/version.go index 5468e71e1d..251d55abba 100644 --- a/params/version.go +++ b/params/version.go @@ -22,8 +22,8 @@ import ( const ( VersionMajor = 1 // Major version component of the current release - VersionMinor = 1 // Minor version component of the current release - VersionPatch = 21 // Patch version component of the current release + VersionMinor = 2 // Minor version component of the current release + VersionPatch = 0 // Patch version component of the current release VersionMeta = "" // Version metadata to append to the version string ) diff --git a/rpc/client.go b/rpc/client.go index a89f8ba18c..c8a1a343bc 100644 --- a/rpc/client.go +++ b/rpc/client.go @@ -187,6 +187,18 @@ func DialContext(ctx context.Context, rawurl string) (*Client, error) { } } +// DialOptions creates a new RPC client for the given URL. You can supply any of the +// pre-defined client options to configure the underlying transport. +// +// The context is used to cancel or time out the initial connection establishment. It does +// not affect subsequent interactions with the client. +// +// The client reconnects automatically when the connection is lost. +func DialOptions(ctx context.Context, rawurl string, options ...ClientOption) (*Client, error) { + // just for prysm compile pass + return nil, fmt.Errorf("not supported") +} + // Client retrieves the client from the context, if any. This can be used to perform // 'reverse calls' in a handler method. func ClientFromContext(ctx context.Context) (*Client, bool) { diff --git a/rpc/client_opt.go b/rpc/client_opt.go new file mode 100644 index 0000000000..5ad7c22b3c --- /dev/null +++ b/rpc/client_opt.go @@ -0,0 +1,106 @@ +// Copyright 2022 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 rpc + +import ( + "net/http" + + "github.com/gorilla/websocket" +) + +// ClientOption is a configuration option for the RPC client. +type ClientOption interface { + applyOption(*clientConfig) +} + +type clientConfig struct { + httpClient *http.Client + httpHeaders http.Header + httpAuth HTTPAuth + + wsDialer *websocket.Dialer +} + +func (cfg *clientConfig) initHeaders() { + if cfg.httpHeaders == nil { + cfg.httpHeaders = make(http.Header) + } +} + +func (cfg *clientConfig) setHeader(key, value string) { + cfg.initHeaders() + cfg.httpHeaders.Set(key, value) +} + +type optionFunc func(*clientConfig) + +func (fn optionFunc) applyOption(opt *clientConfig) { + fn(opt) +} + +// WithWebsocketDialer configures the websocket.Dialer used by the RPC client. +func WithWebsocketDialer(dialer websocket.Dialer) ClientOption { + return optionFunc(func(cfg *clientConfig) { + cfg.wsDialer = &dialer + }) +} + +// WithHeader configures HTTP headers set by the RPC client. Headers set using this option +// will be used for both HTTP and WebSocket connections. +func WithHeader(key, value string) ClientOption { + return optionFunc(func(cfg *clientConfig) { + cfg.initHeaders() + cfg.httpHeaders.Set(key, value) + }) +} + +// WithHeaders configures HTTP headers set by the RPC client. Headers set using this +// option will be used for both HTTP and WebSocket connections. +func WithHeaders(headers http.Header) ClientOption { + return optionFunc(func(cfg *clientConfig) { + cfg.initHeaders() + for k, vs := range headers { + cfg.httpHeaders[k] = vs + } + }) +} + +// WithHTTPClient configures the http.Client used by the RPC client. +func WithHTTPClient(c *http.Client) ClientOption { + return optionFunc(func(cfg *clientConfig) { + cfg.httpClient = c + }) +} + +// WithHTTPAuth configures HTTP request authentication. The given provider will be called +// whenever a request is made. Note that only one authentication provider can be active at +// any time. +func WithHTTPAuth(a HTTPAuth) ClientOption { + if a == nil { + panic("nil auth") + } + return optionFunc(func(cfg *clientConfig) { + cfg.httpAuth = a + }) +} + +// A HTTPAuth function is called by the client whenever a HTTP request is sent. +// The function must be safe for concurrent use. +// +// Usually, HTTPAuth functions will call h.Set("authorization", "...") to add +// auth information to the request. +type HTTPAuth func(h http.Header) error diff --git a/rpc/subscription.go b/rpc/subscription.go index 942e764e5d..d7ba784fc5 100644 --- a/rpc/subscription.go +++ b/rpc/subscription.go @@ -34,7 +34,7 @@ import ( var ( // ErrNotificationsUnsupported is returned when the connection doesn't support notifications ErrNotificationsUnsupported = errors.New("notifications not supported") - // ErrNotificationNotFound is returned when the notification for the given id is not found + // ErrSubscriptionNotFound is returned when the notification for the given id is not found ErrSubscriptionNotFound = errors.New("subscription not found") ) diff --git a/rpc/types.go b/rpc/types.go index 959e383723..151e5ee27e 100644 --- a/rpc/types.go +++ b/rpc/types.go @@ -60,13 +60,15 @@ type jsonWriter interface { type BlockNumber int64 const ( - PendingBlockNumber = BlockNumber(-2) - LatestBlockNumber = BlockNumber(-1) - EarliestBlockNumber = BlockNumber(0) + SafeBlockNumber = BlockNumber(-4) + FinalizedBlockNumber = BlockNumber(-3) + PendingBlockNumber = BlockNumber(-2) + LatestBlockNumber = BlockNumber(-1) + EarliestBlockNumber = BlockNumber(0) ) // UnmarshalJSON parses the given JSON fragment into a BlockNumber. It supports: -// - "latest", "earliest" or "pending" as string arguments +// - "safe", "finalized", "latest", "earliest" or "pending" as string arguments // - the block number // Returned errors: // - an invalid block number error when the given argument isn't a known strings @@ -87,6 +89,12 @@ func (bn *BlockNumber) UnmarshalJSON(data []byte) error { case "pending": *bn = PendingBlockNumber return nil + case "finalized": + *bn = FinalizedBlockNumber + return nil + case "safe": + *bn = SafeBlockNumber + return nil } blckNum, err := hexutil.DecodeUint64(input) @@ -101,7 +109,7 @@ func (bn *BlockNumber) UnmarshalJSON(data []byte) error { } // MarshalText implements encoding.TextMarshaler. It marshals: -// - "latest", "earliest" or "pending" as strings +// - "safe", "finalized", "latest", "earliest" or "pending" as strings // - other numbers as hex func (bn BlockNumber) MarshalText() ([]byte, error) { switch bn { @@ -111,6 +119,10 @@ func (bn BlockNumber) MarshalText() ([]byte, error) { return []byte("latest"), nil case PendingBlockNumber: return []byte("pending"), nil + case FinalizedBlockNumber: + return []byte("finalized"), nil + case SafeBlockNumber: + return []byte("safe"), nil default: return hexutil.Uint64(bn).MarshalText() } @@ -157,6 +169,14 @@ func (bnh *BlockNumberOrHash) UnmarshalJSON(data []byte) error { bn := PendingBlockNumber bnh.BlockNumber = &bn return nil + case "finalized": + bn := FinalizedBlockNumber + bnh.BlockNumber = &bn + return nil + case "safe": + bn := SafeBlockNumber + bnh.BlockNumber = &bn + return nil default: if len(input) == 66 { hash := common.Hash{} diff --git a/tests/truffle/.env b/tests/truffle/.env index d933e4cfef..e2b3e27f5c 100644 --- a/tests/truffle/.env +++ b/tests/truffle/.env @@ -1,4 +1,4 @@ -BSC_CHAIN_ID="99" +BSC_CHAIN_ID=99 CLUSTER_CIDR=99.1.0.0/16 BOOTSTRAP_PUB_KEY=177ae5db445a2f70db781b019aedd928f5b1528a7a43448840b022408f9a21509adcce0b37c87d59da68d47a16879cc1e95a62bbac9723f7b22f4365b2afabbe BOOTSTRAP_TCP_PORT=30311 diff --git a/tests/truffle/scripts/bootstrap.sh b/tests/truffle/scripts/bootstrap.sh index 0e5e00df99..653059115d 100755 --- a/tests/truffle/scripts/bootstrap.sh +++ b/tests/truffle/scripts/bootstrap.sh @@ -42,19 +42,38 @@ function init_genesis_data() { fi } +function prepareBLSWallet(){ + node_id=$1 + echo "123456" > ${workspace}/storage/${node_id}/blspassword.txt + expect ${workspace}/scripts/create_bls_key.sh ${workspace}/storage/${node_id} + + sed -i -e 's/DataDir/BLSPasswordFile = \"{{BLSPasswordFile}}\"\nBLSWalletDir = \"{{BLSWalletDir}}\"\nDataDir/g' ${workspace}/storage/${node_id}/config.toml + PassWordPath="/root/.ethereum/blspassword.txt" + sed -i -e "s:{{BLSPasswordFile}}:${PassWordPath}:g" ${workspace}/storage/${node_id}/config.toml + WalletPath="/root/.ethereum/bls/wallet" + sed -i -e "s:{{BLSWalletDir}}:${WalletPath}:g" ${workspace}/storage/${node_id}/config.toml +} + prepare -# First, generate config for each validator +# Step 1, generate config for each validator for((i=1;i<=${NUMS_OF_VALIDATOR};i++)); do init_validator "bsc-validator${i}" done -# Then, use validator configs to generate genesis file +# Step 2, use validator configs to generate genesis file generate_genesis -# Finally, use genesis file to init cluster data +# Step 3, use genesis file to init cluster data init_genesis_data bsc-rpc bsc-rpc for((i=1;i<=${NUMS_OF_VALIDATOR};i++)); do init_genesis_data validator "bsc-validator${i}" done + +#Step 4, prepare bls wallet, used by fast finality vote +prepareBLSWallet bsc-rpc + +for((i=1;i<=${NUMS_OF_VALIDATOR};i++)); do + prepareBLSWallet "bsc-validator${i}" +done \ No newline at end of file diff --git a/tests/truffle/scripts/create_bls_key.sh b/tests/truffle/scripts/create_bls_key.sh new file mode 100644 index 0000000000..a1a4d97bd6 --- /dev/null +++ b/tests/truffle/scripts/create_bls_key.sh @@ -0,0 +1,17 @@ +#!/usr/bin/expect +# 6 num wanted +set wallet_password 123456 +# 10 characters at least wanted +set account_password 1234567890 + +set timeout 5 +spawn geth bls account new --datadir [lindex $argv 0] +expect "*assword:*" +send "$wallet_password\r" +expect "*assword:*" +send "$wallet_password\r" +expect "*assword:*" +send "$account_password\r" +expect "*assword:*" +send "$account_password\r" +expect EOF \ No newline at end of file