tests: add testutils for integration testing (#132)

* tests: add testutils for integration testing

* update util

* fix config

* more updates

* rand chain-id

* add rpc client integration test example

* makefile

* rename

* updates to makefile
This commit is contained in:
Federico Kunze 2021-06-25 05:18:37 -04:00 committed by GitHub
parent 61260dfda8
commit 459a290951
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 1726 additions and 2216 deletions

483
Makefile
View File

@ -1,72 +1,21 @@
# Copyright 2018 Tendermint. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#!/usr/bin/make -f
VERSION := $(shell echo $(shell git describe --tags) | sed 's/^v//')
PACKAGES_NOSIMULATION=$(shell go list ./... | grep -v '/simulation')
PACKAGES_SIMTEST=$(shell go list ./... | grep '/simulation')
VERSION := $(shell echo $(shell git describe --always) | sed 's/^v//')
COMMIT := $(shell git log -1 --format='%H')
PACKAGES=$(shell go list ./... | grep -Ev 'vendor|importer|rpc/tester')
DOCKER_TAG = unstable
DOCKER_IMAGE = tharsis/ethermint
DOCKER_BUF := docker run -v $(shell pwd):/workspace --workdir /workspace bufbuild/buf
LEDGER_ENABLED ?= true
BINDIR ?= $(GOPATH)/bin
ETHERMINT_BINARY = ethermintd
ETHERMINT_DIR = ethermint
GO_MOD=GO111MODULE=on
BUILDDIR ?= $(CURDIR)/build
SIMAPP = ./app
LEDGER_ENABLED ?= true
HTTPS_GIT := https://github.com/tharsis/ethermint.git
DOCKER := $(shell which docker)
DOCKER_BUF := $(DOCKER) run --rm -v $(CURDIR):/workspace --workdir /workspace bufbuild/buf
ifeq ($(OS),Windows_NT)
DETECTED_OS := windows
else
UNAME_S = $(shell uname -s)
ifeq ($(UNAME_S),Darwin)
DETECTED_OS := mac
else
DETECTED_OS := linux
endif
endif
export DETECTED_OS
export GO111MODULE = on
##########################################
# Find OS and Go environment
# GO contains the Go binary
# FS contains the OS file separator
##########################################
ifeq ($(OS),Windows_NT)
GO := $(shell where go.exe 2> NUL)
FS := "\\"
else
GO := $(shell command -v go 2> /dev/null)
FS := "/"
endif
ifeq ($(GO),)
$(error could not find go. Is it in PATH? $(GO))
endif
GOPATH ?= $(shell $(GO) env GOPATH)
BINDIR ?= $(GOPATH)/bin
RUNSIM = $(BINDIR)/runsim
# process build tags
build_tags = netgo
@ -93,7 +42,7 @@ ifeq ($(LEDGER_ENABLED),true)
endif
endif
ifeq ($(WITH_CLEVELDB),yes)
ifeq (cleveldb,$(findstring cleveldb,$(COSMOS_BUILD_OPTIONS)))
build_tags += gcc
endif
build_tags += $(BUILD_TAGS)
@ -112,44 +61,60 @@ ldflags = -X github.com/cosmos/cosmos-sdk/version.Name=ethermint \
-X github.com/cosmos/cosmos-sdk/version.Commit=$(COMMIT) \
-X "github.com/cosmos/cosmos-sdk/version.BuildTags=$(build_tags_comma_sep)"
ifeq ($(WITH_CLEVELDB),yes)
# DB backend selection
ifeq (cleveldb,$(findstring cleveldb,$(COSMOS_BUILD_OPTIONS)))
ldflags += -X github.com/cosmos/cosmos-sdk/types.DBBackend=cleveldb
endif
ifeq (badgerdb,$(findstring badgerdb,$(COSMOS_BUILD_OPTIONS)))
ldflags += -X github.com/cosmos/cosmos-sdk/types.DBBackend=badgerdb
endif
# handle rocksdb
ifeq (rocksdb,$(findstring rocksdb,$(COSMOS_BUILD_OPTIONS)))
CGO_ENABLED=1
BUILD_TAGS += rocksdb
ldflags += -X github.com/cosmos/cosmos-sdk/types.DBBackend=rocksdb
endif
# handle boltdb
ifeq (boltdb,$(findstring boltdb,$(COSMOS_BUILD_OPTIONS)))
BUILD_TAGS += boltdb
ldflags += -X github.com/cosmos/cosmos-sdk/types.DBBackend=boltdb
endif
ifeq (,$(findstring nostrip,$(COSMOS_BUILD_OPTIONS)))
ldflags += -w -s
endif
ldflags += $(LDFLAGS)
ldflags := $(strip $(ldflags))
BUILD_FLAGS := -tags "$(build_tags)" -ldflags '$(ldflags)'
# check for nostrip option
ifeq (,$(findstring nostrip,$(COSMOS_BUILD_OPTIONS)))
BUILD_FLAGS += -trimpath
endif
all: tools install
all: tools build lint test
# # The below include contains the tools and runsim targets.
# include contrib/devtools/Makefile
###############################################################################
### Build ###
###############################################################################
build: go.sum
BUILD_TARGETS := build install
ifeq ($(OS), Windows_NT)
go build $(BUILD_FLAGS) -o build/$(ETHERMINT_BINARY).exe ./cmd/$(ETHERMINT_BINARY)
else
go build $(BUILD_FLAGS) -o build/$(ETHERMINT_BINARY) ./cmd/$(ETHERMINT_BINARY)
endif
build: BUILD_ARGS=-o $(BUILDDIR)/
build-linux:
GOOS=linux GOARCH=amd64 LEDGER_ENABLED=false $(MAKE) build
build-ethermint: go.sum
mkdir -p $(BUILDDIR)
go build $(BUILD_FLAGS) -o $(BUILDDIR) ./cmd/$(ETHERMINT_BINARY)
$(BUILD_TARGETS): go.sum $(BUILDDIR)/
go $@ -mod=readonly $(BUILD_FLAGS) $(BUILD_ARGS) ./...
build-ethermint-linux: go.sum
GOOS=linux GOARCH=amd64 CGO_ENABLED=1 $(MAKE) build-ethermint
$(BUILDDIR)/:
mkdir -p $(BUILDDIR)/
.PHONY: build build-ethermint build-ethermint-linux
install:
${GO_MOD} go install $(BUILD_FLAGS) ./cmd/$(ETHERMINT_BINARY)
clean:
@rm -rf ./build ./vendor
.PHONY: install clean
docker-build:
# TODO replace with kaniko
@ -167,6 +132,20 @@ docker-build:
docker-localnet:
docker build -f ./networks/local/ethermintnode/Dockerfile . -t ethermintd/node
$(MOCKS_DIR):
mkdir -p $(MOCKS_DIR)
distclean: clean tools-clean
clean:
rm -rf \
$(BUILDDIR)/ \
artifacts/ \
tmp-swagger-gen/
.PHONY: distclean clean
###############################################################################
### Tools & Dependencies ###
###############################################################################
@ -261,159 +240,10 @@ docs-tools-stamp: docs-tools
.PHONY: runsim statik tools contract-tools docs-tools proto-tools tools-stamp tools-clean docs-tools-stamp
###############################################################################
### Tests & Simulation ###
###############################################################################
test: test-unit
test-unit:
@go test -v ./... $(PACKAGES)
test-race:
@go test -v --vet=off -race ./... $(PACKAGES)
test-import:
@go test ./tests/importer -v --vet=off --run=TestImportBlocks --datadir tmp \
--blockchain blockchain
rm -rf tests/importer/tmp
test-rpc:
./scripts/integration-test-all.sh -t "rpc" -q 1 -z 1 -s 2 -m "rpc" -r "true"
test-rpc-pending:
./scripts/integration-test-all.sh -t "pending" -q 1 -z 1 -s 2 -m "pending" -r "true"
test-contract:
@type "npm" 2> /dev/null || (echo 'Npm does not exist. Please install node.js and npm."' && exit 1)
@type "solcjs" 2> /dev/null || (echo 'Solcjs does not exist. Please install solcjs using make contract-tools."' && exit 1)
@type "protoc" 2> /dev/null || (echo 'Failed to install protoc. Please reinstall protoc using make contract-tools.' && exit 1)
bash scripts/contract-test.sh
test-sim-nondeterminism:
@echo "Running non-determinism test..."
@go test -mod=readonly $(SIMAPP) -run TestAppStateDeterminism -Enabled=true \
-NumBlocks=100 -BlockSize=200 -Commit=true -Period=0 -v -timeout 24h
test-sim-custom-genesis-fast:
@echo "Running custom genesis simulation..."
@echo "By default, ${HOME}/.$(ETHERMINT_DIR)/config/genesis.json will be used."
@go test -mod=readonly $(SIMAPP) -run TestFullAppSimulation -Genesis=${HOME}/.$(ETHERMINT_DIR)/config/genesis.json \
-Enabled=true -NumBlocks=100 -BlockSize=200 -Commit=true -Seed=99 -Period=5 -v -timeout 24h
test-sim-import-export: runsim
@echo "Running application import/export simulation. This may take several minutes..."
@$(BINDIR)/runsim -Jobs=4 -SimAppPkg=$(SIMAPP) -ExitOnFail -Genesis=${HOME}/.$(ETHERMINT_DIR)/config/genesis.json 50 5 TestAppImportExport
test-sim-after-import: runsim
@echo "Running application simulation-after-import. This may take several minutes..."
@$(BINDIR)/runsim -Jobs=4 -SimAppPkg=$(SIMAPP) -Genesis=${HOME}/.$(ETHERMINT_DIR)/config/genesis.json -ExitOnFail 50 5 TestAppSimulationAfterImport
test-sim-custom-genesis-multi-seed: runsim
@echo "Running multi-seed custom genesis simulation..."
@echo "By default, ${HOME}/.$(ETHERMINT_DIR)/config/genesis.json will be used."
@$(BINDIR)/runsim -Jobs=4 -SimAppPkg=$(SIMAPP) -ExitOnFail -Genesis=${HOME}/.$(ETHERMINT_DIR)/config/genesis.json 400 5 TestFullAppSimulation
test-sim-multi-seed-long: runsim
@echo "Running multi-seed application simulation. This may take awhile!"
@$(BINDIR)/runsim -Jobs=4 -SimAppPkg=$(SIMAPP) -ExitOnFail 500 50 TestFullAppSimulation
test-sim-multi-seed-short: runsim
@echo "Running multi-seed application simulation. This may take awhile!"
@$(BINDIR)/runsim -Jobs=4 -SimAppPkg=$(SIMAPP) -ExitOnFail 50 10 TestFullAppSimulation
test-solidity:
@echo "Beginning solidity tests..."
./scripts/run-solidity-tests.sh
.PHONY: test test-unit test-race test-import test-rpc test-contract test-solidity
.PHONY: test-sim-nondeterminism test-sim-custom-genesis-fast test-sim-import-export test-sim-after-import \
test-sim-custom-genesis-multi-seed test-sim-multi-seed-long test-sim-multi-seed-short
###############################################################################
### Linting ###
###############################################################################
lint:
golangci-lint run --out-format=tab --issues-exit-code=0
find . -name '*.go' -type f -not -path "./vendor*" -not -path "*.git*" | xargs gofmt -d -s
format:
find . -name '*.go' -type f -not -path "./vendor*" -not -path "*.git*" -not -name '*.pb.go' | xargs gofmt -w -s
find . -name '*.go' -type f -not -path "./vendor*" -not -path "*.git*" -not -name '*.pb.go' | xargs misspell -w
find . -name '*.go' -type f -not -path "./vendor*" -not -path "*.git*" -not -name '*.pb.go' | xargs goimports -w -local github.com/tendermint
find . -name '*.go' -type f -not -path "./vendor*" -not -path "*.git*" -not -name '*.pb.go' | xargs goimports -w -local github.com/ethereum/go-ethereum
find . -name '*.go' -type f -not -path "./vendor*" -not -path "*.git*" -not -name '*.pb.go' | xargs goimports -w -local github.com/cosmos/cosmos-sdk
find . -name '*.go' -type f -not -path "./vendor*" -not -path "*.git*" -not -name '*.pb.go' | xargs goimports -w -local github.com/tharsis/ethermint
.PHONY: lint format
###############################################################################
### Protobuf ###
###############################################################################
proto-all: proto-format proto-lint proto-gen
proto-gen:
@echo "Generating Protobuf files"
$(DOCKER) run --rm -v $(CURDIR):/workspace --workdir /workspace tendermintdev/sdk-proto-gen sh ./scripts/protocgen.sh
proto-format:
@echo "Formatting Protobuf files"
$(DOCKER) run --rm -v $(CURDIR):/workspace \
--workdir /workspace tendermintdev/docker-build-proto \
find ./ -not -path "./third_party/*" -name *.proto -exec clang-format -i {} \;
proto-swagger-gen:
@./scripts/protoc-swagger-gen.sh
proto-format:
find ./ -not -path "./third_party/*" -name *.proto -exec clang-format -i {} \;
proto-lint:
@$(DOCKER_BUF) check lint --error-format=json
proto-check-breaking:
@$(DOCKER_BUF) check breaking --against-input $(HTTPS_GIT)#branch=development
TM_URL = https://raw.githubusercontent.com/tendermint/tendermint/v0.34.1/proto/tendermint
GOGO_PROTO_URL = https://raw.githubusercontent.com/regen-network/protobuf/cosmos
COSMOS_SDK_URL = https://raw.githubusercontent.com/cosmos/cosmos-sdk/master
COSMOS_PROTO_URL = https://raw.githubusercontent.com/regen-network/cosmos-proto/master
TM_CRYPTO_TYPES = third_party/proto/tendermint/crypto
TM_ABCI_TYPES = third_party/proto/tendermint/abci
TM_TYPES = third_party/proto/tendermint/types
GOGO_PROTO_TYPES = third_party/proto/gogoproto
COSMOS_SDK_PROTO = third_party/proto/cosmos-sdk
COSMOS_PROTO_TYPES = third_party/proto/cosmos_proto
proto-update-deps:
@mkdir -p $(GOGO_PROTO_TYPES)
@curl -sSL $(GOGO_PROTO_URL)/gogoproto/gogo.proto > $(GOGO_PROTO_TYPES)/gogo.proto
@mkdir -p $(COSMOS_PROTO_TYPES)
@curl -sSL $(COSMOS_PROTO_URL)/cosmos.proto > $(COSMOS_PROTO_TYPES)/cosmos.proto
## Importing of tendermint protobuf definitions currently requires the
## use of `sed` in order to build properly with cosmos-sdk's proto file layout
## (which is the standard Buf.build FILE_LAYOUT)
## Issue link: https://github.com/tendermint/tendermint/issues/5021
@mkdir -p $(TM_ABCI_TYPES)
@curl -sSL $(TM_URL)/abci/types.proto > $(TM_ABCI_TYPES)/types.proto
@mkdir -p $(TM_TYPES)
@curl -sSL $(TM_URL)/types/types.proto > $(TM_TYPES)/types.proto
@mkdir -p $(TM_CRYPTO_TYPES)
@curl -sSL $(TM_URL)/crypto/proof.proto > $(TM_CRYPTO_TYPES)/proof.proto
@curl -sSL $(TM_URL)/crypto/keys.proto > $(TM_CRYPTO_TYPES)/keys.proto
.PHONY: proto-all proto-gen proto-gen-any proto-swagger-gen proto-format proto-lint proto-check-breaking proto-update-deps
go.sum: go.mod
echo "Ensure dependencies have not been modified ..." >&2
go mod verify
go mod tidy
###############################################################################
### Documentation ###
@ -446,10 +276,203 @@ build-docs:
done < versions ;
.PHONY: build-docs
###############################################################################
### Tests & Simulation ###
###############################################################################
test: test-unit
test-all: test-unit test-race
TEST_PACKAGES=./...
TEST_TARGETS := test-unit test-race
# Test runs-specific rules. To add a new test target, just add
# a new rule, customise ARGS or TEST_PACKAGES ad libitum, and
# append the new rule to the TEST_TARGETS list.
test-unit: ARGS=-tags='norace'
test-race: ARGS=-race
test-race: TEST_PACKAGES=$(PACKAGES_NOSIMULATION)
$(TEST_TARGETS): run-tests
run-tests:
ifneq (,$(shell which tparse 2>/dev/null))
go test -mod=readonly -json $(ARGS) $(EXTRA_ARGS) $(TEST_PACKAGES) | tparse
else
go test -mod=readonly $(ARGS) $(EXTRA_ARGS) $(TEST_PACKAGES)
endif
test-import:
@go test ./tests/importer -v --vet=off --run=TestImportBlocks --datadir tmp \
--blockchain blockchain
rm -rf tests/importer/tmp
test-rpc:
./scripts/integration-test-all.sh -t "rpc" -q 1 -z 1 -s 2 -m "rpc" -r "true"
test-rpc-pending:
./scripts/integration-test-all.sh -t "pending" -q 1 -z 1 -s 2 -m "pending" -r "true"
test-contract:
@type "npm" 2> /dev/null || (echo 'Npm does not exist. Please install node.js and npm."' && exit 1)
@type "solcjs" 2> /dev/null || (echo 'Solcjs does not exist. Please install solcjs using make contract-tools."' && exit 1)
@type "protoc" 2> /dev/null || (echo 'Failed to install protoc. Please reinstall protoc using make contract-tools.' && exit 1)
bash scripts/contract-test.sh
test-solidity:
@echo "Beginning solidity tests..."
./scripts/run-solidity-tests.sh
.PHONY: run-tests test test-all test-import test-rpc test-contract test-solidity $(TEST_TARGETS)
test-sim-nondeterminism:
@echo "Running non-determinism test..."
@go test -mod=readonly $(SIMAPP) -run TestAppStateDeterminism -Enabled=true \
-NumBlocks=100 -BlockSize=200 -Commit=true -Period=0 -v -timeout 24h
test-sim-custom-genesis-fast:
@echo "Running custom genesis simulation..."
@echo "By default, ${HOME}/.$(ETHERMINT_DIR)/config/genesis.json will be used."
@go test -mod=readonly $(SIMAPP) -run TestFullAppSimulation -Genesis=${HOME}/.$(ETHERMINT_DIR)/config/genesis.json \
-Enabled=true -NumBlocks=100 -BlockSize=200 -Commit=true -Seed=99 -Period=5 -v -timeout 24h
test-sim-import-export: runsim
@echo "Running application import/export simulation. This may take several minutes..."
@$(BINDIR)/runsim -Jobs=4 -SimAppPkg=$(SIMAPP) -ExitOnFail 50 5 TestAppImportExport
test-sim-after-import: runsim
@echo "Running application simulation-after-import. This may take several minutes..."
@$(BINDIR)/runsim -Jobs=4 -SimAppPkg=$(SIMAPP) -ExitOnFail 50 5 TestAppSimulationAfterImport
test-sim-custom-genesis-multi-seed: runsim
@echo "Running multi-seed custom genesis simulation..."
@echo "By default, ${HOME}/.$(ETHERMINT_DIR)/config/genesis.json will be used."
@$(BINDIR)/runsim -Genesis=${HOME}/.$(ETHERMINT_DIR)/config/genesis.json -SimAppPkg=$(SIMAPP) -ExitOnFail 400 5 TestFullAppSimulation
test-sim-multi-seed-long: runsim
@echo "Running long multi-seed application simulation. This may take awhile!"
@$(BINDIR)/runsim -Jobs=4 -SimAppPkg=$(SIMAPP) -ExitOnFail 500 50 TestFullAppSimulation
test-sim-multi-seed-short: runsim
@echo "Running short multi-seed application simulation. This may take awhile!"
@$(BINDIR)/runsim -Jobs=4 -SimAppPkg=$(SIMAPP) -ExitOnFail 50 10 TestFullAppSimulation
test-sim-benchmark-invariants:
@echo "Running simulation invariant benchmarks..."
@go test -mod=readonly $(SIMAPP) -benchmem -bench=BenchmarkInvariants -run=^$ \
-Enabled=true -NumBlocks=1000 -BlockSize=200 \
-Period=1 -Commit=true -Seed=57 -v -timeout 24h
.PHONY: \
test-sim-nondeterminism \
test-sim-custom-genesis-fast \
test-sim-import-export \
test-sim-after-import \
test-sim-custom-genesis-multi-seed \
test-sim-multi-seed-short \
test-sim-multi-seed-long \
test-sim-benchmark-invariants
test-cover:
@export VERSION=$(VERSION); bash -x contrib/test_cover.sh
.PHONY: test-cover
benchmark:
@go test -mod=readonly -bench=. $(PACKAGES_NOSIMULATION)
.PHONY: benchmark
###############################################################################
### Linting ###
###############################################################################
lint:
golangci-lint run --out-format=tab
lint-fix:
golangci-lint run --fix --out-format=tab --issues-exit-code=0
.PHONY: lint lint-fix
format:
find . -name '*.go' -type f -not -path "./vendor*" -not -path "*.git*" -not -path "./client/docs/statik/statik.go" -not -name '*.pb.go' | xargs gofmt -w -s
find . -name '*.go' -type f -not -path "./vendor*" -not -path "*.git*" -not -path "./client/docs/statik/statik.go" -not -name '*.pb.go' | xargs misspell -w
find . -name '*.go' -type f -not -path "./vendor*" -not -path "*.git*" -not -path "./client/docs/statik/statik.go" -not -name '*.pb.go' | xargs goimports -w -local github.com/tharsis/ethermint
.PHONY: format
###############################################################################
### Protobuf ###
###############################################################################
containerProtoVer=v0.2
containerProtoImage=tendermintdev/sdk-proto-gen:$(containerProtoVer)
containerProtoGen=cosmos-sdk-proto-gen-$(containerProtoVer)
containerProtoGenSwagger=cosmos-sdk-proto-gen-swagger-$(containerProtoVer)
containerProtoFmt=cosmos-sdk-proto-fmt-$(containerProtoVer)
proto-all: proto-format proto-lint proto-gen
proto-gen:
@echo "Generating Protobuf files"
$(DOCKER) run --rm -v $(CURDIR):/workspace --workdir /workspace tendermintdev/sdk-proto-gen sh ./scripts/protocgen.sh
proto-swagger-gen:
@echo "Generating Protobuf Swagger"
@./scripts/protoc-swagger-gen.sh
proto-format:
@echo "Formatting Protobuf files"
find ./ -not -path "./third_party/*" -name *.proto -exec clang-format -i {} \;
proto-lint:
@$(DOCKER_BUF) check lint --error-format=json
proto-check-breaking:
@$(DOCKER_BUF) check breaking --against-input $(HTTPS_GIT)#branch=main
TM_URL = https://raw.githubusercontent.com/tendermint/tendermint/v0.34.1/proto/tendermint
GOGO_PROTO_URL = https://raw.githubusercontent.com/regen-network/protobuf/cosmos
COSMOS_SDK_URL = https://raw.githubusercontent.com/cosmos/cosmos-sdk/v0.42.5
COSMOS_PROTO_URL = https://raw.githubusercontent.com/regen-network/cosmos-proto/master
TM_CRYPTO_TYPES = third_party/proto/tendermint/crypto
TM_ABCI_TYPES = third_party/proto/tendermint/abci
TM_TYPES = third_party/proto/tendermint/types
GOGO_PROTO_TYPES = third_party/proto/gogoproto
COSMOS_PROTO_TYPES = third_party/proto/cosmos_proto
proto-update-deps:
@mkdir -p $(GOGO_PROTO_TYPES)
@curl -sSL $(GOGO_PROTO_URL)/gogoproto/gogo.proto > $(GOGO_PROTO_TYPES)/gogo.proto
@mkdir -p $(COSMOS_PROTO_TYPES)
@curl -sSL $(COSMOS_PROTO_URL)/cosmos.proto > $(COSMOS_PROTO_TYPES)/cosmos.proto
## Importing of tendermint protobuf definitions currently requires the
## use of `sed` in order to build properly with cosmos-sdk's proto file layout
## (which is the standard Buf.build FILE_LAYOUT)
## Issue link: https://github.com/tendermint/tendermint/issues/5021
@mkdir -p $(TM_ABCI_TYPES)
@curl -sSL $(TM_URL)/abci/types.proto > $(TM_ABCI_TYPES)/types.proto
@mkdir -p $(TM_TYPES)
@curl -sSL $(TM_URL)/types/types.proto > $(TM_TYPES)/types.proto
@mkdir -p $(TM_CRYPTO_TYPES)
@curl -sSL $(TM_URL)/crypto/proof.proto > $(TM_CRYPTO_TYPES)/proof.proto
@curl -sSL $(TM_URL)/crypto/keys.proto > $(TM_CRYPTO_TYPES)/keys.proto
.PHONY: proto-all proto-gen proto-gen-any proto-swagger-gen proto-format proto-lint proto-check-breaking proto-update-deps
###############################################################################
### Localnet ###
###############################################################################
# Run a 4-node testnet locally
build-docker-local-ethermint:
@$(MAKE) -C networks/local

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -8,14 +8,11 @@ import (
"github.com/cosmos/cosmos-sdk/telemetry"
serverconfig "github.com/cosmos/cosmos-sdk/server/config"
storetypes "github.com/cosmos/cosmos-sdk/store/types"
"github.com/cosmos/cosmos-sdk/server/config"
sdk "github.com/cosmos/cosmos-sdk/types"
)
const (
defaultMinGasPrices = ""
// DefaultGRPCAddress is the default address the gRPC server binds to.
DefaultGRPCAddress = "0.0.0.0:9900"
@ -26,67 +23,6 @@ const (
DefaultEVMWSAddress = "0.0.0.0:1318"
)
// BaseConfig defines the server's basic configuration
type BaseConfig struct {
// The minimum gas prices a validator is willing to accept for processing a
// transaction. A transaction's fees must meet the minimum of any denomination
// specified in this config (e.g. 0.25token1;0.0001token2).
MinGasPrices string `mapstructure:"minimum-gas-prices"`
Pruning string `mapstructure:"pruning"`
PruningKeepRecent string `mapstructure:"pruning-keep-recent"`
PruningKeepEvery string `mapstructure:"pruning-keep-every"`
PruningInterval string `mapstructure:"pruning-interval"`
// HaltHeight contains a non-zero block height at which a node will gracefully
// halt and shutdown that can be used to assist upgrades and testing.
//
// Note: Commitment of state will be attempted on the corresponding block.
HaltHeight uint64 `mapstructure:"halt-height"`
// HaltTime contains a non-zero minimum block time (in Unix seconds) at which
// a node will gracefully halt and shutdown that can be used to assist
// upgrades and testing.
//
// Note: Commitment of state will be attempted on the corresponding block.
HaltTime uint64 `mapstructure:"halt-time"`
// MinRetainBlocks defines the minimum block height offset from the current
// block being committed, such that blocks past this offset may be pruned
// from Tendermint. It is used as part of the process of determining the
// ResponseCommit.RetainHeight value during ABCI Commit. A value of 0 indicates
// that no blocks should be pruned.
//
// This configuration value is only responsible for pruning Tendermint blocks.
// It has no bearing on application state pruning which is determined by the
// "pruning-*" configurations.
//
// Note: Tendermint block pruning is dependant on this parameter in conunction
// with the unbonding (safety threshold) period, state pruning and state sync
// snapshot parameters to determine the correct minimum value of
// ResponseCommit.RetainHeight.
MinRetainBlocks uint64 `mapstructure:"min-retain-blocks"`
// InterBlockCache enables inter-block caching.
InterBlockCache bool `mapstructure:"inter-block-cache"`
// IndexEvents defines the set of events in the form {eventType}.{attributeKey},
// which informs Tendermint what to index. If empty, all events will be indexed.
IndexEvents []string `mapstructure:"index-events"`
}
// APIConfig defines the API listener configuration.
type APIConfig = serverconfig.APIConfig
// GRPCConfig defines configuration for the gRPC server.
type GRPCConfig struct {
// Enable defines if the gRPC server should be enabled.
Enable bool `mapstructure:"enable"`
// Address defines the API server to listen on
Address string `mapstructure:"address"`
}
// EVMRPCConfig defines configuration for the EVM RPC server.
type EVMRPCConfig struct {
// Enable defines if the EVM RPC server should be enabled.
@ -97,27 +33,26 @@ type EVMRPCConfig struct {
WsAddress string `mapstructure:"ws-address"`
}
// StateSyncConfig defines the state sync snapshot configuration.
type StateSyncConfig struct {
// SnapshotInterval sets the interval at which state sync snapshots are taken.
// 0 disables snapshots. Must be a multiple of PruningKeepEvery.
SnapshotInterval uint64 `mapstructure:"snapshot-interval"`
// SnapshotKeepRecent sets the number of recent state sync snapshots to keep.
// 0 keeps all snapshots.
SnapshotKeepRecent uint32 `mapstructure:"snapshot-keep-recent"`
}
// Config defines the server's top level configuration
type Config struct {
BaseConfig `mapstructure:",squash"`
config.BaseConfig `mapstructure:",squash"`
// Telemetry defines the application telemetry configuration
Telemetry telemetry.Config `mapstructure:"telemetry"`
API APIConfig `mapstructure:"api"`
GRPC GRPCConfig `mapstructure:"grpc"`
EVMRPC EVMRPCConfig `mapstructure:"evm-rpc"`
StateSync StateSyncConfig `mapstructure:"state-sync"`
Telemetry telemetry.Config `mapstructure:"telemetry"`
API config.APIConfig `mapstructure:"api"`
GRPC config.GRPCConfig `mapstructure:"grpc"`
EVMRPC EVMRPCConfig `mapstructure:"evm-rpc"`
StateSync config.StateSyncConfig `mapstructure:"state-sync"`
}
func (c *Config) ToSDKConfig() *config.Config {
return &config.Config{
BaseConfig: c.BaseConfig,
Telemetry: c.Telemetry,
API: c.API,
GRPC: c.GRPC,
StateSync: c.StateSync,
}
}
// SetMinGasPrices sets the validator's minimum gas prices.
@ -149,95 +84,36 @@ func (c *Config) GetMinGasPrices() sdk.DecCoins {
// DefaultConfig returns server's default configuration.
func DefaultConfig() *Config {
cfg := config.DefaultConfig()
return &Config{
BaseConfig: BaseConfig{
MinGasPrices: defaultMinGasPrices,
InterBlockCache: true,
Pruning: storetypes.PruningOptionNothing,
PruningKeepRecent: "0",
PruningKeepEvery: "0",
PruningInterval: "0",
MinRetainBlocks: 0,
IndexEvents: make([]string, 0),
},
Telemetry: telemetry.Config{
Enabled: false,
GlobalLabels: [][]string{},
},
API: APIConfig{
Enable: true,
Swagger: true,
Address: "tcp://0.0.0.0:10337",
MaxOpenConnections: 1000,
RPCReadTimeout: 10,
RPCMaxBodyBytes: 1000000,
},
GRPC: GRPCConfig{
Enable: true,
Address: DefaultGRPCAddress,
},
BaseConfig: cfg.BaseConfig,
Telemetry: cfg.Telemetry,
API: cfg.API,
GRPC: cfg.GRPC,
EVMRPC: EVMRPCConfig{
Enable: true,
RPCAddress: DefaultEVMAddress,
WsAddress: DefaultEVMWSAddress,
},
StateSync: StateSyncConfig{
SnapshotInterval: 0,
SnapshotKeepRecent: 2,
},
StateSync: cfg.StateSync,
}
}
// GetConfig returns a fully parsed Config object.
func GetConfig(v *viper.Viper) Config {
globalLabelsRaw := v.Get("telemetry.global-labels").([]interface{})
globalLabels := make([][]string, 0, len(globalLabelsRaw))
cfg := config.GetConfig(v)
return Config{
BaseConfig: BaseConfig{
MinGasPrices: v.GetString("minimum-gas-prices"),
InterBlockCache: v.GetBool("inter-block-cache"),
Pruning: v.GetString("pruning"),
PruningKeepRecent: v.GetString("pruning-keep-recent"),
PruningKeepEvery: v.GetString("pruning-keep-every"),
PruningInterval: v.GetString("pruning-interval"),
HaltHeight: v.GetUint64("halt-height"),
HaltTime: v.GetUint64("halt-time"),
IndexEvents: v.GetStringSlice("index-events"),
MinRetainBlocks: v.GetUint64("min-retain-blocks"),
},
Telemetry: telemetry.Config{
ServiceName: v.GetString("telemetry.service-name"),
Enabled: v.GetBool("telemetry.enabled"),
EnableHostname: v.GetBool("telemetry.enable-hostname"),
EnableHostnameLabel: v.GetBool("telemetry.enable-hostname-label"),
EnableServiceLabel: v.GetBool("telemetry.enable-service-label"),
PrometheusRetentionTime: v.GetInt64("telemetry.prometheus-retention-time"),
GlobalLabels: globalLabels,
},
API: APIConfig{
Enable: v.GetBool("api.enable"),
Swagger: v.GetBool("api.swagger"),
Address: v.GetString("api.address"),
MaxOpenConnections: v.GetUint("api.max-open-connections"),
RPCReadTimeout: v.GetUint("api.rpc-read-timeout"),
RPCWriteTimeout: v.GetUint("api.rpc-write-timeout"),
RPCMaxBodyBytes: v.GetUint("api.rpc-max-body-bytes"),
EnableUnsafeCORS: v.GetBool("api.enabled-unsafe-cors"),
},
GRPC: GRPCConfig{
Enable: v.GetBool("grpc.enable"),
Address: v.GetString("grpc.address"),
},
BaseConfig: cfg.BaseConfig,
Telemetry: cfg.Telemetry,
API: cfg.API,
GRPC: cfg.GRPC,
EVMRPC: EVMRPCConfig{
Enable: v.GetBool("evm-rpc.enable"),
RPCAddress: v.GetString("evm-rpc.address"),
WsAddress: v.GetString("evm-rpc.ws-address"),
},
StateSync: StateSyncConfig{
SnapshotInterval: v.GetUint64("state-sync.snapshot-interval"),
SnapshotKeepRecent: v.GetUint32("state-sync.snapshot-keep-recent"),
},
StateSync: cfg.StateSync,
}
}

View File

@ -24,7 +24,6 @@ import (
pvm "github.com/tendermint/tendermint/privval"
"github.com/tendermint/tendermint/proxy"
"github.com/tendermint/tendermint/rpc/client/local"
rpcclient "github.com/tendermint/tendermint/rpc/jsonrpc/client"
dbm "github.com/tendermint/tm-db"
"github.com/cosmos/cosmos-sdk/client"
@ -42,6 +41,7 @@ import (
"github.com/tharsis/ethermint/cmd/ethermintd/config"
"github.com/tharsis/ethermint/ethereum/rpc"
ethsrv "github.com/tharsis/ethermint/server"
)
// Tendermint full-node start flags
@ -230,6 +230,7 @@ func startInProcess(ctx *server.Context, clientCtx client.Context, appCreator ty
grpcSrv, err = servergrpc.StartGRPCServer(clientCtx, app, config.GRPC.Address)
if err != nil {
log.WithError(err).Errorln("failed to boot GRPC server")
return err
}
}
@ -242,7 +243,7 @@ func startInProcess(ctx *server.Context, clientCtx client.Context, appCreator ty
tmEndpoint := "/websocket"
tmRPCAddr := cfg.RPC.ListenAddress
log.Infoln("EVM RPC Connecting to Tendermint WebSocket at", tmRPCAddr+tmEndpoint)
tmWsClient := connectTmWS(tmRPCAddr, tmEndpoint)
tmWsClient := ethsrv.ConnectTmWS(tmRPCAddr, tmEndpoint)
rpcServer := ethrpc.NewServer()
apis := rpc.GetRPCAPIs(clientCtx, tmWsClient)
@ -253,6 +254,7 @@ func startInProcess(ctx *server.Context, clientCtx client.Context, appCreator ty
"namespace": api.Namespace,
"service": api.Service,
}).WithError(err).Fatalln("failed to register service in EVM RPC namespace")
return err
}
}
@ -260,7 +262,7 @@ func startInProcess(ctx *server.Context, clientCtx client.Context, appCreator ty
r.HandleFunc("/", rpcServer.ServeHTTP).Methods("POST")
if grpcSrv != nil {
grpcWeb := grpcweb.WrapServer(grpcSrv)
mountGrpcWebServices(r, grpcWeb, grpcweb.ListGRPCResources(grpcSrv))
ethsrv.MountGRPCWebServices(r, grpcWeb, grpcweb.ListGRPCResources(grpcSrv))
}
handlerWithCors := cors.New(cors.Options{
@ -308,7 +310,7 @@ func startInProcess(ctx *server.Context, clientCtx client.Context, appCreator ty
_, port, _ := net.SplitHostPort(config.EVMRPC.RPCAddress)
// allocate separate WS connection to Tendermint
tmWsClient = connectTmWS(tmRPCAddr, tmEndpoint)
tmWsClient = ethsrv.ConnectTmWS(tmRPCAddr, tmEndpoint)
wsSrv = rpc.NewWebsocketsServer(tmWsClient, "localhost:"+port, config.EVMRPC.WsAddress)
go wsSrv.Start()
}
@ -391,50 +393,6 @@ func startInProcess(ctx *server.Context, clientCtx client.Context, appCreator ty
return nil
}
func connectTmWS(tmRPCAddr, tmEndpoint string) *rpcclient.WSClient {
tmWsClient, err := rpcclient.NewWS(tmRPCAddr, tmEndpoint,
rpcclient.MaxReconnectAttempts(256),
rpcclient.ReadWait(120*time.Second),
rpcclient.WriteWait(120*time.Second),
rpcclient.PingPeriod(50*time.Second),
rpcclient.OnReconnect(func() {
log.WithField("tendermint_rpc", tmRPCAddr+tmEndpoint).
Debugln("EVM RPC reconnects to Tendermint WS")
}),
)
if err != nil {
log.WithError(err).Fatalln("Tendermint WS client could not be created for ", tmRPCAddr+tmEndpoint)
} else if err := tmWsClient.OnStart(); err != nil {
log.WithError(err).Fatalln("Tendermint WS client could not start for ", tmRPCAddr+tmEndpoint)
}
return tmWsClient
}
func mountGrpcWebServices(
router *mux.Router,
grpcWeb *grpcweb.WrappedGrpcServer,
grpcResources []string,
) {
for _, res := range grpcResources {
log.Printf("[GRPC Web] HTTP POST mounted on %s", res)
s := router.Methods("POST").Subrouter()
s.HandleFunc(res, func(resp http.ResponseWriter, req *http.Request) {
if grpcWeb.IsGrpcWebSocketRequest(req) {
grpcWeb.HandleGrpcWebsocketRequest(resp, req)
return
}
if grpcWeb.IsGrpcWebRequest(req) {
grpcWeb.HandleGrpcWebRequest(resp, req)
return
}
})
}
}
func openDB(rootDir string) (dbm.DB, error) {
dataDir := filepath.Join(rootDir, "data")
return sdk.NewLevelDB("application", dataDir)

View File

@ -125,7 +125,7 @@ func init() {
}
var fileDescriptor_8bbc409ef04b39de = []byte{
// 201 bytes of a gzipped FileDescriptorProto
// 202 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x32, 0x4c, 0x2d, 0xc9, 0x48,
0x2d, 0xca, 0xcd, 0xcc, 0x2b, 0xd1, 0x4f, 0x2e, 0xaa, 0x2c, 0x28, 0xc9, 0xd7, 0x2f, 0x33, 0x4c,
0xcc, 0x29, 0xc8, 0x48, 0x34, 0xd4, 0x4f, 0x2d, 0xc9, 0x28, 0x4e, 0x4d, 0x2e, 0x30, 0x32, 0x35,
@ -134,11 +134,11 @@ var fileDescriptor_8bbc409ef04b39de = []byte{
0x0f, 0xd6, 0xa2, 0x0f, 0x62, 0x41, 0x74, 0x2b, 0x29, 0x70, 0xb1, 0x05, 0x94, 0x26, 0x79, 0xa7,
0x56, 0x0a, 0x09, 0x70, 0x31, 0x67, 0xa7, 0x56, 0x4a, 0x30, 0x2a, 0x30, 0x6a, 0xf0, 0x04, 0x81,
0x98, 0x56, 0x2c, 0x33, 0x16, 0xc8, 0x33, 0x28, 0x49, 0x73, 0xb1, 0x07, 0x14, 0x65, 0x96, 0x61,
0x55, 0xe2, 0xe4, 0x79, 0xe2, 0x91, 0x1c, 0xe3, 0x85, 0x47, 0x72, 0x8c, 0x0f, 0x1e, 0xc9, 0x31,
0x4e, 0x78, 0x2c, 0xc7, 0x70, 0xe1, 0xb1, 0x1c, 0xc3, 0x8d, 0xc7, 0x72, 0x0c, 0x51, 0xfa, 0xe9,
0x99, 0x25, 0x19, 0xa5, 0x49, 0x7a, 0xc9, 0xf9, 0xb9, 0xfa, 0xc9, 0xf9, 0xc5, 0xb9, 0xf9, 0xc5,
0xfa, 0x18, 0x7e, 0x43, 0x76, 0x5f, 0x12, 0x1b, 0xd8, 0x41, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff,
0xff, 0x06, 0xa5, 0x4e, 0xba, 0x03, 0x01, 0x00, 0x00,
0x55, 0xe2, 0xe4, 0x75, 0xe2, 0x91, 0x1c, 0xe3, 0x85, 0x47, 0x72, 0x8c, 0x0f, 0x1e, 0xc9, 0x31,
0x4e, 0x78, 0x2c, 0xc7, 0x70, 0xe1, 0xb1, 0x1c, 0xc3, 0x8d, 0xc7, 0x72, 0x0c, 0x51, 0x06, 0xe9,
0x99, 0x25, 0x19, 0xa5, 0x49, 0x7a, 0xc9, 0xf9, 0xb9, 0xfa, 0x25, 0x19, 0x89, 0x45, 0xc5, 0x99,
0xc5, 0xfa, 0x18, 0x9e, 0x43, 0x76, 0x60, 0x12, 0x1b, 0xd8, 0x45, 0xc6, 0x80, 0x00, 0x00, 0x00,
0xff, 0xff, 0x37, 0x56, 0x7b, 0x6c, 0x04, 0x01, 0x00, 0x00,
}
func (m *PubKey) Marshal() (dAtA []byte, err error) {

View File

@ -15,7 +15,7 @@ import (
evmtypes "github.com/tharsis/ethermint/x/evm/types"
)
// MakeEncodingConfig creates an EncodingConfig for testing
// MakeConfig creates an EncodingConfig for testing
func MakeConfig(mb module.BasicManager) params.EncodingConfig {
cdc := amino.NewLegacyAmino()
interfaceRegistry := types.NewInterfaceRegistry()

4
go.mod
View File

@ -45,8 +45,8 @@ require (
github.com/tyler-smith/go-bip39 v1.1.0
github.com/xlab/closer v0.0.0-20190328110542-03326addb7c2
github.com/xlab/suplog v1.3.0
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a // indirect
google.golang.org/genproto v0.0.0-20210607140030-00d4fb20b1ae
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e // indirect
google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84
google.golang.org/grpc v1.38.0
gopkg.in/yaml.v2 v2.4.0
nhooyr.io/websocket v1.8.7 // indirect

13
go.sum
View File

@ -1037,8 +1037,8 @@ golang.org/x/crypto v0.0.0-20201117144127-c1f2f97bffc9/go.mod h1:jdWPYTVW3xRLrWP
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-20210513164829-c07d793c2f9a h1:kr2P4QFmQr29mSLA43kwrOcgcReGTfbE9N577tCTuBc=
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e h1:gsTQYXdTw2Gq7RBsWvlQ91b+aEQ6bXFUngBGuR8sPpI=
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@ -1235,8 +1235,9 @@ golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210420205809-ac73e9fd8988/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007 h1:gG67DSER+11cZvqIMb8S8bt0vZtiN6xWYARwirrOSfE=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 h1:SrN+KX8Art/Sf4HNj6Zcz06G7VEz+7w9tdXTPOZ7+l4=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/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 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
@ -1253,6 +1254,7 @@ golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxb
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/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=
@ -1313,6 +1315,7 @@ golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4f
golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
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=
@ -1405,8 +1408,8 @@ google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6D
google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
google.golang.org/genproto v0.0.0-20210607140030-00d4fb20b1ae h1:2dB4bZ/B7RJdKuvHk3mKTzL2xwrikb+Y/QQy7WdyBPk=
google.golang.org/genproto v0.0.0-20210607140030-00d4fb20b1ae/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84 h1:R1r5J0u6Cx+RNl/6mezTw6oA14cmKC96FeUwL6A9bd4=
google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24=
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.19.1/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=

55
server/util.go Normal file
View File

@ -0,0 +1,55 @@
package server
import (
"net/http"
"time"
"github.com/gorilla/mux"
"github.com/improbable-eng/grpc-web/go/grpcweb"
rpcclient "github.com/tendermint/tendermint/rpc/jsonrpc/client"
log "github.com/xlab/suplog"
)
func ConnectTmWS(tmRPCAddr, tmEndpoint string) *rpcclient.WSClient {
tmWsClient, err := rpcclient.NewWS(tmRPCAddr, tmEndpoint,
rpcclient.MaxReconnectAttempts(256),
rpcclient.ReadWait(120*time.Second),
rpcclient.WriteWait(120*time.Second),
rpcclient.PingPeriod(50*time.Second),
rpcclient.OnReconnect(func() {
log.WithField("tendermint_rpc", tmRPCAddr+tmEndpoint).
Debugln("EVM RPC reconnects to Tendermint WS")
}),
)
if err != nil {
log.WithError(err).Fatalln("Tendermint WS client could not be created for ", tmRPCAddr+tmEndpoint)
} else if err := tmWsClient.OnStart(); err != nil {
log.WithError(err).Fatalln("Tendermint WS client could not start for ", tmRPCAddr+tmEndpoint)
}
return tmWsClient
}
func MountGRPCWebServices(
router *mux.Router,
grpcWeb *grpcweb.WrappedGrpcServer,
grpcResources []string,
) {
for _, res := range grpcResources {
log.Printf("[GRPC Web] HTTP POST mounted on %s", res)
s := router.Methods("POST").Subrouter()
s.HandleFunc(res, func(resp http.ResponseWriter, req *http.Request) {
if grpcWeb.IsGrpcWebSocketRequest(req) {
grpcWeb.HandleGrpcWebsocketRequest(resp, req)
return
}
if grpcWeb.IsGrpcWebRequest(req) {
grpcWeb.HandleGrpcWebRequest(resp, req)
return
}
})
}
}

View File

@ -0,0 +1,55 @@
package e2e
import (
"context"
"testing"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/stretchr/testify/suite"
"github.com/tharsis/ethermint/testutil/network"
ethermint "github.com/tharsis/ethermint/types"
)
type IntegrationTestSuite struct {
suite.Suite
ctx context.Context
cfg network.Config
network *network.Network
}
func (s *IntegrationTestSuite) SetupSuite() {
s.T().Log("setting up integration test suite")
cfg := network.DefaultConfig()
cfg.NumValidators = 1
s.ctx = context.Background()
s.cfg = cfg
s.network = network.New(s.T(), cfg)
s.Require().NotNil(s.network)
_, err := s.network.WaitForHeight(1)
s.Require().NoError(err)
cl, err := ethclient.Dial(s.network.Validators[0].JSONRPCAddress)
s.Require().NoError(err, "failed to dial JSON-RPC at %s", s.network.Validators[0].JSONRPCAddress)
s.network.Validators[0].JSONRPCClient = cl
}
func (s *IntegrationTestSuite) TestChainID() {
chainID, err := s.network.Validators[0].JSONRPCClient.ChainID(s.ctx)
s.Require().NoError(err)
s.Require().NotNil(chainID)
s.T().Log(chainID.Int64())
eip155ChainID, err := ethermint.ParseChainID(s.network.Config.ChainID)
s.Require().NoError(err)
s.Require().Equal(chainID, eip155ChainID)
}
func TestIntegrationTestSuite(t *testing.T) {
suite.Run(t, new(IntegrationTestSuite))
}

65
testutil/network/doc.go Normal file
View File

@ -0,0 +1,65 @@
/*
Package network implements and exposes a fully operational in-process Tendermint
test network that consists of at least one or potentially many validators. This
test network can be used primarily for integration tests or unit test suites.
The test network utilizes SimApp as the ABCI application and uses all the modules
defined in the Cosmos SDK. An in-process test network can be configured with any
number of validators as well as account funds and even custom genesis state.
When creating a test network, a series of Validator objects are returned. Each
Validator object has useful information such as their address and public key. A
Validator will also provide its RPC, P2P, and API addresses that can be useful
for integration testing. In addition, a Tendermint local RPC client is also provided
which can be handy for making direct RPC calls to Tendermint.
Note, due to limitations in concurrency and the design of the RPC layer in
Tendermint, only the first Validator object will have an RPC and API client
exposed. Due to this exact same limitation, only a single test network can exist
at a time. A caller must be certain it calls Cleanup after it no longer needs
the network.
A typical testing flow might look like the following:
type IntegrationTestSuite struct {
suite.Suite
cfg testutil.Config
network *testutil.Network
}
func (s *IntegrationTestSuite) SetupSuite() {
s.T().Log("setting up integration test suite")
cfg := testutil.DefaultConfig()
cfg.NumValidators = 1
s.cfg = cfg
s.network = testutil.New(s.T(), cfg)
_, err := s.network.WaitForHeight(1)
s.Require().NoError(err)
}
func (s *IntegrationTestSuite) TearDownSuite() {
s.T().Log("tearing down integration test suite")
// This is important and must be called to ensure other tests can create
// a network!
s.network.Cleanup()
}
func (s *IntegrationTestSuite) TestQueryBalancesRequestHandlerFn() {
val := s.network.Validators[0]
baseURL := val.APIAddress
// Use baseURL to make API HTTP requests or use val.RPCClient to make direct
// Tendermint RPC calls.
// ...
}
func TestIntegrationTestSuite(t *testing.T) {
suite.Run(t, new(IntegrationTestSuite))
}
*/
package network

511
testutil/network/network.go Normal file
View File

@ -0,0 +1,511 @@
package network
import (
"bufio"
"context"
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"net/url"
"os"
"path/filepath"
"sync"
"testing"
"time"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethclient"
jsonrpc "github.com/ethereum/go-ethereum/rpc"
"google.golang.org/grpc"
"github.com/stretchr/testify/require"
tmcfg "github.com/tendermint/tendermint/config"
tmflags "github.com/tendermint/tendermint/libs/cli/flags"
"github.com/tendermint/tendermint/libs/log"
tmrand "github.com/tendermint/tendermint/libs/rand"
"github.com/tendermint/tendermint/node"
tmclient "github.com/tendermint/tendermint/rpc/client"
dbm "github.com/tendermint/tm-db"
"github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/tx"
"github.com/cosmos/cosmos-sdk/codec"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
"github.com/cosmos/cosmos-sdk/crypto/keyring"
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
"github.com/cosmos/cosmos-sdk/server"
"github.com/cosmos/cosmos-sdk/server/api"
servertypes "github.com/cosmos/cosmos-sdk/server/types"
"github.com/cosmos/cosmos-sdk/simapp"
"github.com/cosmos/cosmos-sdk/simapp/params"
storetypes "github.com/cosmos/cosmos-sdk/store/types"
sdk "github.com/cosmos/cosmos-sdk/types"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
"github.com/cosmos/cosmos-sdk/x/genutil"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
"github.com/tharsis/ethermint/app"
srvconfig "github.com/tharsis/ethermint/cmd/ethermintd/config"
"github.com/tharsis/ethermint/crypto/hd"
"github.com/tharsis/ethermint/encoding"
ethermint "github.com/tharsis/ethermint/types"
)
// package-wide network lock to only allow one test network at a time
var lock = new(sync.Mutex)
// AppConstructor defines a function which accepts a network configuration and
// creates an ABCI Application to provide to Tendermint.
type AppConstructor = func(val Validator) servertypes.Application
// NewAppConstructor returns a new simapp AppConstructor
func NewAppConstructor(encodingCfg params.EncodingConfig) AppConstructor {
return func(val Validator) servertypes.Application {
return app.NewEthermintApp(
val.Ctx.Logger, dbm.NewMemDB(), nil, true, make(map[int64]bool), val.Ctx.Config.RootDir, 0,
encodingCfg,
simapp.EmptyAppOptions{},
baseapp.SetPruning(storetypes.NewPruningOptionsFromString(val.AppConfig.Pruning)),
baseapp.SetMinGasPrices(val.AppConfig.MinGasPrices),
baseapp.SetTrace(true),
)
}
}
// Config defines the necessary configuration used to bootstrap and start an
// in-process local testing network.
type Config struct {
Codec codec.Marshaler
LegacyAmino *codec.LegacyAmino // TODO: Remove!
InterfaceRegistry codectypes.InterfaceRegistry
TxConfig client.TxConfig
AccountRetriever client.AccountRetriever
AppConstructor AppConstructor // the ABCI application constructor
GenesisState map[string]json.RawMessage // custom gensis state to provide
TimeoutCommit time.Duration // the consensus commitment timeout
ChainID string // the network chain-id
NumValidators int // the total number of validators to create and bond
BondDenom string // the staking bond denomination
MinGasPrices string // the minimum gas prices each validator will accept
AccountTokens sdk.Int // the amount of unique validator tokens (e.g. 1000node0)
StakingTokens sdk.Int // the amount of tokens each validator has available to stake
BondedTokens sdk.Int // the amount of tokens each validator stakes
PruningStrategy string // the pruning strategy each validator will have
EnableLogging bool // enable Tendermint logging to STDOUT
CleanupDir bool // remove base temporary directory during cleanup
SigningAlgo string // signing algorithm for keys
KeyringOptions []keyring.Option
}
// DefaultConfig returns a sane default configuration suitable for nearly all
// testing requirements.
func DefaultConfig() Config {
encCfg := encoding.MakeConfig(app.ModuleBasics)
return Config{
Codec: encCfg.Marshaler,
TxConfig: encCfg.TxConfig,
LegacyAmino: encCfg.Amino,
InterfaceRegistry: encCfg.InterfaceRegistry,
AccountRetriever: authtypes.AccountRetriever{},
AppConstructor: NewAppConstructor(encCfg),
GenesisState: app.NewDefaultGenesisState(),
TimeoutCommit: 2 * time.Second,
ChainID: "ethermint-" + fmt.Sprintf("%d", tmrand.NewRand().Int63n(1000)),
NumValidators: 4,
BondDenom: ethermint.AttoPhoton,
MinGasPrices: fmt.Sprintf("0.000006%s", ethermint.AttoPhoton),
AccountTokens: sdk.TokensFromConsensusPower(1000),
StakingTokens: sdk.TokensFromConsensusPower(500),
BondedTokens: sdk.TokensFromConsensusPower(100),
PruningStrategy: storetypes.PruningOptionNothing,
CleanupDir: true,
SigningAlgo: string(hd.EthSecp256k1Type),
KeyringOptions: []keyring.Option{hd.EthSecp256k1Option()},
}
}
type (
// Network defines a local in-process testing network using SimApp. It can be
// configured to start any number of validators, each with its own RPC and API
// clients. Typically, this test network would be used in client and integration
// testing where user input is expected.
//
// Note, due to Tendermint constraints in regards to RPC functionality, there
// may only be one test network running at a time. Thus, any caller must be
// sure to Cleanup after testing is finished in order to allow other tests
// to create networks. In addition, only the first validator will have a valid
// RPC and API server/client.
Network struct {
T *testing.T
BaseDir string
Validators []*Validator
Config Config
}
// Validator defines an in-process Tendermint validator node. Through this object,
// a client can make RPC and API calls and interact with any client command
// or handler.
Validator struct {
AppConfig *srvconfig.Config
ClientCtx client.Context
Ctx *server.Context
Dir string
NodeID string
PubKey cryptotypes.PubKey
Moniker string
APIAddress string
RPCAddress string
P2PAddress string
JSONRPCAddress string
EthereumAddress common.Address
Address sdk.AccAddress
ValAddress sdk.ValAddress
RPCClient tmclient.Client
JSONRPCClient *ethclient.Client
tmNode *node.Node
api *api.Server
grpc *grpc.Server
jsonRPC *jsonrpc.Server
}
)
// New creates a new Network for integration tests.
func New(t *testing.T, cfg Config) *Network {
// only one caller/test can create and use a network at a time
t.Log("acquiring test network lock")
lock.Lock()
baseDir, err := ioutil.TempDir(t.TempDir(), cfg.ChainID)
require.NoError(t, err)
t.Logf("created temporary directory: %s", baseDir)
network := &Network{
T: t,
BaseDir: baseDir,
Validators: make([]*Validator, cfg.NumValidators),
Config: cfg,
}
t.Log("preparing test network...")
var (
monikers = make([]string, cfg.NumValidators)
nodeIDs = make([]string, cfg.NumValidators)
valPubKeys = make([]cryptotypes.PubKey, cfg.NumValidators)
)
var (
genAccounts []authtypes.GenesisAccount
genBalances []banktypes.Balance
genFiles []string
)
buf := bufio.NewReader(os.Stdin)
// generate private keys, node IDs, and initial transactions
for i := 0; i < cfg.NumValidators; i++ {
appCfg := srvconfig.DefaultConfig()
appCfg.Pruning = cfg.PruningStrategy
appCfg.MinGasPrices = cfg.MinGasPrices
appCfg.API.Enable = true
appCfg.API.Swagger = false
appCfg.Telemetry.Enabled = false
ctx := server.NewDefaultContext()
tmCfg := ctx.Config
tmCfg.Consensus.TimeoutCommit = cfg.TimeoutCommit
// Only allow the first validator to expose an RPC, API and gRPC
// server/client due to Tendermint in-process constraints.
apiAddr := ""
jsonRPCAddr := ""
tmCfg.RPC.ListenAddress = ""
appCfg.GRPC.Enable = false
appCfg.EVMRPC.Enable = false
if i == 0 {
apiListenAddr, _, err := server.FreeTCPAddr()
require.NoError(t, err)
appCfg.API.Address = apiListenAddr
apiURL, err := url.Parse(apiListenAddr)
require.NoError(t, err)
apiAddr = fmt.Sprintf("http://%s:%s", apiURL.Hostname(), apiURL.Port())
jsonRPCListenAddr, _, err := server.FreeTCPAddr()
require.NoError(t, err)
t.Log(jsonRPCListenAddr)
appCfg.EVMRPC.RPCAddress = jsonRPCListenAddr
appCfg.EVMRPC.Enable = true
jsonRPCAPIURL, err := url.Parse(jsonRPCListenAddr)
require.NoError(t, err)
jsonRPCAddr = fmt.Sprintf("http://%s:%s", jsonRPCAPIURL.Hostname(), jsonRPCAPIURL.Port())
rpcAddr, _, err := server.FreeTCPAddr()
require.NoError(t, err)
tmCfg.RPC.ListenAddress = rpcAddr
_, grpcPort, err := server.FreeTCPAddr()
require.NoError(t, err)
appCfg.GRPC.Address = fmt.Sprintf("0.0.0.0:%s", grpcPort)
appCfg.GRPC.Enable = true
}
logger := log.NewNopLogger()
if cfg.EnableLogging {
logger = log.NewTMLogger(log.NewSyncWriter(os.Stdout))
logger, _ = tmflags.ParseLogLevel("info", logger, tmcfg.DefaultLogLevel)
}
ctx.Logger = logger
nodeDirName := fmt.Sprintf("node%d", i)
nodeDir := filepath.Join(network.BaseDir, nodeDirName, "ethermintd")
gentxsDir := filepath.Join(network.BaseDir, "gentxs")
require.NoError(t, os.MkdirAll(filepath.Join(nodeDir, "config"), 0755))
tmCfg.SetRoot(nodeDir)
tmCfg.Moniker = nodeDirName
monikers[i] = nodeDirName
proxyAddr, _, err := server.FreeTCPAddr()
require.NoError(t, err)
tmCfg.ProxyApp = proxyAddr
p2pAddr, _, err := server.FreeTCPAddr()
require.NoError(t, err)
tmCfg.P2P.ListenAddress = p2pAddr
tmCfg.P2P.AddrBookStrict = false
tmCfg.P2P.AllowDuplicateIP = true
nodeID, pubKey, err := genutil.InitializeNodeValidatorFiles(tmCfg)
require.NoError(t, err)
nodeIDs[i] = nodeID
valPubKeys[i] = pubKey
kb, err := keyring.New(sdk.KeyringServiceName(), keyring.BackendTest, nodeDir, buf, cfg.KeyringOptions...)
require.NoError(t, err)
keyringAlgos, _ := kb.SupportedAlgorithms()
algo, err := keyring.NewSigningAlgoFromString(cfg.SigningAlgo, keyringAlgos)
require.NoError(t, err)
addr, secret, err := server.GenerateSaveCoinKey(kb, nodeDirName, true, algo)
require.NoError(t, err)
info := map[string]string{"secret": secret}
infoBz, err := json.Marshal(info)
require.NoError(t, err)
// save private key seed words
require.NoError(t, writeFile(fmt.Sprintf("%v.json", "key_seed"), nodeDir, infoBz))
balances := sdk.NewCoins(
sdk.NewCoin(fmt.Sprintf("%stoken", nodeDirName), cfg.AccountTokens),
sdk.NewCoin(cfg.BondDenom, cfg.StakingTokens),
)
genFiles = append(genFiles, tmCfg.GenesisFile())
genBalances = append(genBalances, banktypes.Balance{Address: addr.String(), Coins: balances.Sort()})
genAccounts = append(genAccounts, authtypes.NewBaseAccount(addr, nil, 0, 0))
commission, err := sdk.NewDecFromStr("0.5")
require.NoError(t, err)
createValMsg, err := stakingtypes.NewMsgCreateValidator(
sdk.ValAddress(addr),
valPubKeys[i],
sdk.NewCoin(cfg.BondDenom, cfg.BondedTokens),
stakingtypes.NewDescription(nodeDirName, "", "", "", ""),
stakingtypes.NewCommissionRates(commission, sdk.OneDec(), sdk.OneDec()),
sdk.OneInt(),
)
require.NoError(t, err)
p2pURL, err := url.Parse(p2pAddr)
require.NoError(t, err)
memo := fmt.Sprintf("%s@%s:%s", nodeIDs[i], p2pURL.Hostname(), p2pURL.Port())
fee := sdk.NewCoins(sdk.NewCoin(fmt.Sprintf("%stoken", nodeDirName), sdk.NewInt(0)))
txBuilder := cfg.TxConfig.NewTxBuilder()
require.NoError(t, txBuilder.SetMsgs(createValMsg))
txBuilder.SetFeeAmount(fee) // Arbitrary fee
txBuilder.SetGasLimit(1000000) // Need at least 100386
txBuilder.SetMemo(memo)
txFactory := tx.Factory{}
txFactory = txFactory.
WithChainID(cfg.ChainID).
WithMemo(memo).
WithKeybase(kb).
WithTxConfig(cfg.TxConfig)
err = tx.Sign(txFactory, nodeDirName, txBuilder, true)
require.NoError(t, err)
txBz, err := cfg.TxConfig.TxJSONEncoder()(txBuilder.GetTx())
require.NoError(t, err)
require.NoError(t, writeFile(fmt.Sprintf("%v.json", nodeDirName), gentxsDir, txBz))
srvconfig.WriteConfigFile(filepath.Join(nodeDir, "config/app.toml"), appCfg)
clientCtx := client.Context{}.
WithKeyringDir(nodeDir).
WithKeyring(kb).
WithHomeDir(tmCfg.RootDir).
WithChainID(cfg.ChainID).
WithInterfaceRegistry(cfg.InterfaceRegistry).
WithJSONMarshaler(cfg.Codec).
WithLegacyAmino(cfg.LegacyAmino).
WithTxConfig(cfg.TxConfig).
WithAccountRetriever(cfg.AccountRetriever)
network.Validators[i] = &Validator{
AppConfig: appCfg,
ClientCtx: clientCtx,
Ctx: ctx,
Dir: filepath.Join(network.BaseDir, nodeDirName),
NodeID: nodeID,
PubKey: pubKey,
Moniker: nodeDirName,
RPCAddress: tmCfg.RPC.ListenAddress,
P2PAddress: tmCfg.P2P.ListenAddress,
APIAddress: apiAddr,
JSONRPCAddress: jsonRPCAddr,
EthereumAddress: common.BytesToAddress(addr),
Address: addr,
ValAddress: sdk.ValAddress(addr),
}
}
require.NoError(t, initGenFiles(cfg, genAccounts, genBalances, genFiles))
require.NoError(t, collectGenFiles(cfg, network.Validators, network.BaseDir))
t.Log("starting test network...")
for _, v := range network.Validators {
require.NoError(t, startInProcess(cfg, v))
}
t.Log("started test network")
// Ensure we cleanup incase any test was abruptly halted (e.g. SIGINT) as any
// defer in a test would not be called.
server.TrapSignal(network.Cleanup)
return network
}
// LatestHeight returns the latest height of the network or an error if the
// query fails or no validators exist.
func (n *Network) LatestHeight() (int64, error) {
if len(n.Validators) == 0 {
return 0, errors.New("no validators available")
}
status, err := n.Validators[0].RPCClient.Status(context.Background())
if err != nil {
return 0, err
}
return status.SyncInfo.LatestBlockHeight, nil
}
// WaitForHeight performs a blocking check where it waits for a block to be
// committed after a given block. If that height is not reached within a timeout,
// an error is returned. Regardless, the latest height queried is returned.
func (n *Network) WaitForHeight(h int64) (int64, error) {
return n.WaitForHeightWithTimeout(h, 10*time.Second)
}
// WaitForHeightWithTimeout is the same as WaitForHeight except the caller can
// provide a custom timeout.
func (n *Network) WaitForHeightWithTimeout(h int64, t time.Duration) (int64, error) {
ticker := time.NewTicker(time.Second)
timeout := time.After(t)
if len(n.Validators) == 0 {
return 0, errors.New("no validators available")
}
var latestHeight int64
val := n.Validators[0]
for {
select {
case <-timeout:
ticker.Stop()
return latestHeight, errors.New("timeout exceeded waiting for block")
case <-ticker.C:
status, err := val.RPCClient.Status(context.Background())
if err == nil && status != nil {
latestHeight = status.SyncInfo.LatestBlockHeight
if latestHeight >= h {
return latestHeight, nil
}
}
}
}
}
// WaitForNextBlock waits for the next block to be committed, returning an error
// upon failure.
func (n *Network) WaitForNextBlock() error {
lastBlock, err := n.LatestHeight()
if err != nil {
return err
}
_, err = n.WaitForHeight(lastBlock + 1)
if err != nil {
return err
}
return err
}
// Cleanup removes the root testing (temporary) directory and stops both the
// Tendermint and API services. It allows other callers to create and start
// test networks. This method must be called when a test is finished, typically
// in a defer.
func (n *Network) Cleanup() {
defer func() {
lock.Unlock()
n.T.Log("released test network lock")
}()
n.T.Log("cleaning up test network...")
for _, v := range n.Validators {
if v.tmNode != nil && v.tmNode.IsRunning() {
_ = v.tmNode.Stop()
}
if v.api != nil {
_ = v.api.Close()
}
if v.grpc != nil {
v.grpc.Stop()
}
if v.jsonRPC != nil {
v.jsonRPC.Stop()
}
}
if n.Config.CleanupDir {
_ = os.RemoveAll(n.BaseDir)
}
n.T.Log("finished cleaning up test network")
}

View File

@ -0,0 +1,46 @@
// +build norace
package network_test
import (
"testing"
"time"
"github.com/stretchr/testify/suite"
"github.com/tharsis/ethermint/testutil/network"
)
type IntegrationTestSuite struct {
suite.Suite
network *network.Network
}
func (s *IntegrationTestSuite) SetupSuite() {
s.T().Log("setting up integration test suite")
s.network = network.New(s.T(), network.DefaultConfig())
s.Require().NotNil(s.network)
_, err := s.network.WaitForHeight(1)
s.Require().NoError(err)
}
func (s *IntegrationTestSuite) TearDownSuite() {
s.T().Log("tearing down integration test suite")
s.network.Cleanup()
}
func (s *IntegrationTestSuite) TestNetwork_Liveness() {
h, err := s.network.WaitForHeightWithTimeout(10, time.Minute)
s.Require().NoError(err, "expected to reach 10 blocks; got %d", h)
latestHeight, err := s.network.LatestHeight()
s.Require().NoError(err, "latest height failed")
s.Require().GreaterOrEqual(latestHeight, h)
}
func TestIntegrationTestSuite(t *testing.T) {
suite.Run(t, new(IntegrationTestSuite))
}

276
testutil/network/util.go Normal file
View File

@ -0,0 +1,276 @@
package network
import (
"encoding/json"
"fmt"
"net/http"
"path/filepath"
"strings"
"time"
jsonrpc "github.com/ethereum/go-ethereum/rpc"
"github.com/gorilla/mux"
"github.com/improbable-eng/grpc-web/go/grpcweb"
"github.com/rs/cors"
tmos "github.com/tendermint/tendermint/libs/os"
"github.com/tendermint/tendermint/node"
"github.com/tendermint/tendermint/p2p"
pvm "github.com/tendermint/tendermint/privval"
"github.com/tendermint/tendermint/proxy"
"github.com/tendermint/tendermint/rpc/client/local"
"github.com/tendermint/tendermint/types"
tmtime "github.com/tendermint/tendermint/types/time"
"github.com/cosmos/cosmos-sdk/server/api"
servergrpc "github.com/cosmos/cosmos-sdk/server/grpc"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
"github.com/cosmos/cosmos-sdk/x/genutil"
genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
"github.com/tharsis/ethermint/ethereum/rpc"
ethsrv "github.com/tharsis/ethermint/server"
ethermint "github.com/tharsis/ethermint/types"
)
func startInProcess(cfg Config, val *Validator) error {
logger := val.Ctx.Logger
tmCfg := val.Ctx.Config
tmCfg.Instrumentation.Prometheus = false
nodeKey, err := p2p.LoadOrGenNodeKey(tmCfg.NodeKeyFile())
if err != nil {
return fmt.Errorf("failed to load or generate node key: %w", err)
}
app := cfg.AppConstructor(*val)
genDocProvider := node.DefaultGenesisDocProviderFunc(tmCfg)
tmNode, err := node.NewNode(
tmCfg,
pvm.LoadOrGenFilePV(tmCfg.PrivValidatorKeyFile(), tmCfg.PrivValidatorStateFile()),
nodeKey,
proxy.NewLocalClientCreator(app),
genDocProvider,
node.DefaultDBProvider,
node.DefaultMetricsProvider(tmCfg.Instrumentation),
logger.With("module", val.Moniker),
)
if err != nil {
return fmt.Errorf("failed to create node: %w", err)
}
if err := tmNode.Start(); err != nil {
return fmt.Errorf("failed to start node: %w", err)
}
val.tmNode = tmNode
if val.RPCAddress != "" {
val.RPCClient = local.New(tmNode)
}
// We'll need a RPC client if the validator exposes a gRPC or REST endpoint.
if val.APIAddress != "" || val.AppConfig.GRPC.Enable {
val.ClientCtx = val.ClientCtx.
WithClient(val.RPCClient)
// Add the tx service in the gRPC router.
app.RegisterTxService(val.ClientCtx)
// Add the tendermint queries service in the gRPC router.
app.RegisterTendermintService(val.ClientCtx)
}
if val.APIAddress != "" {
apiSrv := api.New(val.ClientCtx, logger.With("module", "api-server"))
app.RegisterAPIRoutes(apiSrv, val.AppConfig.API)
errCh := make(chan error)
go func() {
if err := apiSrv.Start(*val.AppConfig.ToSDKConfig()); err != nil {
errCh <- err
}
}()
select {
case err := <-errCh:
return fmt.Errorf("failed to start API server: %w", err)
case <-time.After(5 * time.Second): // assume server started successfully
}
val.api = apiSrv
}
if val.AppConfig.GRPC.Enable {
grpcSrv, err := servergrpc.StartGRPCServer(val.ClientCtx, app, val.AppConfig.GRPC.Address)
if err != nil {
return fmt.Errorf("failed to start gRPC server: %w", err)
}
val.grpc = grpcSrv
}
if val.AppConfig.EVMRPC.Enable {
tmEndpoint := "/websocket"
tmRPCAddr := val.Ctx.Config.RPC.ListenAddress
tmWsClient := ethsrv.ConnectTmWS(tmRPCAddr, tmEndpoint)
val.jsonRPC = jsonrpc.NewServer()
apis := rpc.GetRPCAPIs(val.ClientCtx, tmWsClient)
for _, api := range apis {
if err := val.jsonRPC.RegisterName(api.Namespace, api.Service); err != nil {
return fmt.Errorf("failed to register JSON-RPC namespace %s: %w", api.Namespace, err)
}
}
r := mux.NewRouter()
r.HandleFunc("/", val.jsonRPC.ServeHTTP).Methods("POST")
if val.grpc != nil {
grpcWeb := grpcweb.WrapServer(val.grpc)
ethsrv.MountGRPCWebServices(r, grpcWeb, grpcweb.ListGRPCResources(val.grpc))
}
handlerWithCors := cors.New(cors.Options{
AllowedOrigins: []string{"*"},
AllowedMethods: []string{
http.MethodHead,
http.MethodGet,
http.MethodPost,
http.MethodPut,
http.MethodPatch,
http.MethodDelete,
},
AllowedHeaders: []string{"*"},
AllowCredentials: false,
OptionsPassthrough: false,
})
httpSrv := &http.Server{
Addr: strings.TrimPrefix(val.AppConfig.EVMRPC.RPCAddress, "tcp://"), // FIXME: timeouts
// Addr: val.AppConfig.EVMRPC.RPCAddress, // FIXME: address has too many colons
Handler: handlerWithCors.Handler(r),
}
httpSrvDone := make(chan struct{}, 1)
errCh := make(chan error)
go func() {
if err := httpSrv.ListenAndServe(); err != nil {
if err == http.ErrServerClosed {
close(httpSrvDone)
return
}
errCh <- err
}
}()
select {
case err := <-errCh:
return fmt.Errorf("JSON-RPC go routine failed to start: %w", err)
case <-time.After(1 * time.Second): // assume EVM RPC server started successfully
}
}
return nil
}
func collectGenFiles(cfg Config, vals []*Validator, outputDir string) error {
genTime := tmtime.Now()
for i := 0; i < cfg.NumValidators; i++ {
tmCfg := vals[i].Ctx.Config
nodeDir := filepath.Join(outputDir, vals[i].Moniker, "ethermintd")
gentxsDir := filepath.Join(outputDir, "gentxs")
tmCfg.Moniker = vals[i].Moniker
tmCfg.SetRoot(nodeDir)
initCfg := genutiltypes.NewInitConfig(cfg.ChainID, gentxsDir, vals[i].NodeID, vals[i].PubKey)
genFile := tmCfg.GenesisFile()
genDoc, err := types.GenesisDocFromFile(genFile)
if err != nil {
return fmt.Errorf("failed to create genesis doc: %w", err)
}
appState, err := genutil.GenAppStateFromConfig(cfg.Codec, cfg.TxConfig,
tmCfg, initCfg, *genDoc, banktypes.GenesisBalancesIterator{})
if err != nil {
return fmt.Errorf("failed to create app state: %w", err)
}
// overwrite each validator's genesis file to have a canonical genesis time
if err := genutil.ExportGenesisFileWithTime(genFile, cfg.ChainID, nil, appState, genTime); err != nil {
return fmt.Errorf("failed to export genesis: %w", err)
}
}
return nil
}
func initGenFiles(cfg Config, genAccounts []authtypes.GenesisAccount, genBalances []banktypes.Balance, genFiles []string) error {
// set the accounts in the genesis state
var authGenState authtypes.GenesisState
cfg.Codec.MustUnmarshalJSON(cfg.GenesisState[authtypes.ModuleName], &authGenState)
accounts, err := authtypes.PackAccounts(genAccounts)
if err != nil {
return err
}
authGenState.Accounts = accounts
cfg.GenesisState[authtypes.ModuleName] = cfg.Codec.MustMarshalJSON(&authGenState)
// set the balances in the genesis state
var bankGenState banktypes.GenesisState
cfg.Codec.MustUnmarshalJSON(cfg.GenesisState[banktypes.ModuleName], &bankGenState)
bankGenState.Balances = genBalances
cfg.GenesisState[banktypes.ModuleName] = cfg.Codec.MustMarshalJSON(&bankGenState)
var stakingGenState stakingtypes.GenesisState
cfg.Codec.MustUnmarshalJSON(cfg.GenesisState[stakingtypes.ModuleName], &stakingGenState)
stakingGenState.Params.BondDenom = ethermint.AttoPhoton
cfg.GenesisState[stakingtypes.ModuleName] = cfg.Codec.MustMarshalJSON(&stakingGenState)
appGenStateJSON, err := json.MarshalIndent(cfg.GenesisState, "", " ")
if err != nil {
return err
}
genDoc := types.GenesisDoc{
ChainID: cfg.ChainID,
AppState: appGenStateJSON,
Validators: nil,
}
// generate empty genesis files for each validator and save
for i := 0; i < cfg.NumValidators; i++ {
if err := genDoc.SaveAs(genFiles[i]); err != nil {
return err
}
}
return nil
}
func writeFile(name string, dir string, contents []byte) error {
writePath := filepath.Join(dir)
file := filepath.Join(writePath, name)
err := tmos.EnsureDir(writePath, 0755)
if err != nil {
return err
}
return tmos.WriteFile(file, contents, 0644)
}

View File

@ -73,7 +73,7 @@ func init() {
}
var fileDescriptor_68a082a27334c0d8 = []byte{
// 316 bytes of a gzipped FileDescriptorProto
// 324 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0x4b, 0x2d, 0xc9, 0x48,
0x2d, 0xca, 0xcd, 0xcc, 0x2b, 0xd1, 0x2f, 0xa9, 0x2c, 0x48, 0x2d, 0xd6, 0x2f, 0x33, 0x4c, 0xcc,
0x29, 0xc8, 0x48, 0x34, 0xd4, 0x4f, 0x4c, 0x4e, 0xce, 0x2f, 0xcd, 0x2b, 0xd1, 0x2b, 0x28, 0xca,
@ -90,10 +90,11 @@ var fileDescriptor_68a082a27334c0d8 = []byte{
0x20, 0x0e, 0x10, 0xdb, 0x23, 0xb1, 0x38, 0xc3, 0xca, 0xa9, 0x63, 0x81, 0x3c, 0xc3, 0x8c, 0x05,
0xf2, 0x0c, 0x2f, 0x16, 0xc8, 0x33, 0x5c, 0xda, 0xa2, 0x6b, 0x94, 0x9e, 0x59, 0x92, 0x51, 0x9a,
0xa4, 0x97, 0x9c, 0x9f, 0x0b, 0xf5, 0x22, 0x94, 0xd2, 0x2d, 0x4e, 0xc9, 0xd6, 0xaf, 0x80, 0x04,
0x0e, 0x24, 0xe0, 0xa0, 0xb6, 0x7a, 0x3a, 0x59, 0x9f, 0x78, 0x24, 0xc7, 0x78, 0xe1, 0x91, 0x1c,
0x0e, 0x24, 0xe0, 0xa0, 0xb6, 0x7a, 0x3a, 0xd9, 0x9c, 0x78, 0x24, 0xc7, 0x78, 0xe1, 0x91, 0x1c,
0xe3, 0x83, 0x47, 0x72, 0x8c, 0x13, 0x1e, 0xcb, 0x31, 0x5c, 0x78, 0x2c, 0xc7, 0x70, 0xe3, 0xb1,
0x1c, 0x43, 0x94, 0x22, 0xa6, 0x69, 0x68, 0xd1, 0x94, 0xc4, 0x06, 0x0e, 0x2b, 0x63, 0x40, 0x00,
0x00, 0x00, 0xff, 0xff, 0x31, 0x10, 0xf5, 0x99, 0xc0, 0x01, 0x00, 0x00,
0x1c, 0x43, 0x94, 0x12, 0x92, 0x69, 0x25, 0x19, 0x89, 0x45, 0xc5, 0x99, 0xc5, 0xfa, 0x68, 0xf1,
0x94, 0xc4, 0x06, 0x0e, 0x2c, 0x63, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0xa3, 0x92, 0x9c, 0xa9,
0xc1, 0x01, 0x00, 0x00,
}
func (m *EthAccount) Marshal() (dAtA []byte, err error) {

View File

@ -670,103 +670,103 @@ func init() {
func init() { proto.RegisterFile("ethermint/evm/v1alpha1/evm.proto", fileDescriptor_98f00fcca8b6b943) }
var fileDescriptor_98f00fcca8b6b943 = []byte{
// 1527 bytes of a gzipped FileDescriptorProto
// 1532 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x57, 0xbd, 0x6f, 0x1b, 0x47,
0x16, 0x17, 0x3f, 0x44, 0x2d, 0x87, 0x2b, 0x8a, 0x37, 0xd6, 0xe9, 0x68, 0x1b, 0xc7, 0xe5, 0xed,
0x01, 0x67, 0x1d, 0x60, 0x4b, 0x96, 0x0c, 0xe1, 0x04, 0x03, 0x57, 0x90, 0x96, 0x6c, 0x09, 0x96,
0xef, 0x84, 0xb1, 0xce, 0x3e, 0xa4, 0x21, 0x86, 0xbb, 0xe3, 0xe5, 0x46, 0xbb, 0x3b, 0xcc, 0xce,
0x90, 0x26, 0x03, 0x04, 0x48, 0x99, 0x32, 0xe9, 0x52, 0xba, 0xce, 0x5f, 0x62, 0xa4, 0x72, 0x19,
0xa4, 0xd8, 0x04, 0x74, 0xa7, 0x92, 0x4d, 0x9a, 0x00, 0x09, 0xe6, 0x63, 0x29, 0x52, 0x1f, 0x01,
0x08, 0x55, 0x9c, 0xf7, 0xe6, 0xcd, 0xef, 0x37, 0xef, 0xcd, 0xfb, 0x58, 0x82, 0x3a, 0xe1, 0x1d,
0x12, 0x87, 0x7e, 0xc4, 0x37, 0x49, 0x3f, 0xdc, 0xec, 0x6f, 0xe1, 0xa0, 0xdb, 0xc1, 0x5b, 0x42,
0xd8, 0xe8, 0xc6, 0x94, 0x53, 0xb8, 0x36, 0xb1, 0xd8, 0x10, 0xca, 0xd4, 0xe2, 0xce, 0xaa, 0x47,
0x3d, 0x2a, 0x4d, 0x36, 0xc5, 0x4a, 0x59, 0xdb, 0xbf, 0x66, 0x40, 0xe1, 0x18, 0xc7, 0x38, 0x64,
0x70, 0x0b, 0x14, 0x49, 0x3f, 0x6c, 0xb9, 0x24, 0xa2, 0x61, 0x35, 0x53, 0xcf, 0xac, 0x17, 0x9b,
0xab, 0xe3, 0xc4, 0xaa, 0x0c, 0x71, 0x18, 0x3c, 0xb6, 0x27, 0x5b, 0x36, 0x32, 0x48, 0x3f, 0xdc,
0x13, 0x4b, 0xf8, 0x6f, 0xb0, 0x4c, 0x22, 0xdc, 0x0e, 0x48, 0xcb, 0x89, 0x09, 0xe6, 0xa4, 0x9a,
0xad, 0x67, 0xd6, 0x8d, 0x66, 0x75, 0x9c, 0x58, 0xab, 0xfa, 0xd8, 0xf4, 0xb6, 0x8d, 0x4c, 0x25,
0x3f, 0x91, 0x22, 0xfc, 0x17, 0x28, 0xa5, 0xfb, 0x38, 0x08, 0xaa, 0x39, 0x79, 0x78, 0x6d, 0x9c,
0x58, 0x70, 0xf6, 0x30, 0x0e, 0x02, 0x1b, 0x01, 0x7d, 0x14, 0x07, 0x01, 0x6c, 0x00, 0x40, 0x06,
0x3c, 0xc6, 0x2d, 0xe2, 0x77, 0x59, 0x35, 0x5f, 0xcf, 0xad, 0xe7, 0x9a, 0xf6, 0x28, 0xb1, 0x8a,
0xfb, 0x42, 0xbb, 0x7f, 0x78, 0xcc, 0xc6, 0x89, 0xf5, 0x27, 0x0d, 0x32, 0x31, 0xb4, 0x51, 0x51,
0x0a, 0xfb, 0x7e, 0x97, 0x3d, 0xce, 0x7f, 0xfb, 0xce, 0x5a, 0xb0, 0xdf, 0x95, 0x41, 0xe9, 0x49,
0x07, 0xfb, 0xd1, 0x13, 0x1a, 0xbd, 0xf1, 0x3d, 0xf8, 0x19, 0x58, 0xe9, 0xd0, 0x90, 0x30, 0x4e,
0xb0, 0xdb, 0x6a, 0x07, 0xd4, 0x39, 0xd5, 0x91, 0x38, 0x78, 0x9f, 0x58, 0x0b, 0x3f, 0x26, 0xd6,
0x3f, 0x3c, 0x9f, 0x77, 0x7a, 0xed, 0x0d, 0x87, 0x86, 0x9b, 0x0e, 0x65, 0x21, 0x65, 0xfa, 0xe7,
0x01, 0x73, 0x4f, 0x37, 0xf9, 0xb0, 0x4b, 0xd8, 0xc6, 0x61, 0xc4, 0xc7, 0x89, 0xb5, 0xa6, 0xe8,
0x2f, 0xc0, 0xd9, 0xa8, 0x3c, 0xd1, 0x34, 0x85, 0x02, 0x7e, 0x01, 0xca, 0x2e, 0xa6, 0xad, 0x37,
0x34, 0x3e, 0xd5, 0x8c, 0x59, 0xc9, 0xf8, 0x7a, 0x3e, 0xc6, 0x51, 0x62, 0x99, 0x7b, 0x8d, 0xff,
0x3e, 0xa5, 0xf1, 0xa9, 0xc4, 0x1d, 0x27, 0xd6, 0x9f, 0xd5, 0x0d, 0x66, 0xd1, 0x6d, 0x64, 0xba,
0x98, 0x4e, 0xcc, 0xe0, 0x6b, 0x50, 0x99, 0x18, 0xb0, 0x5e, 0xb7, 0x4b, 0x63, 0xae, 0x1f, 0xe2,
0xc1, 0x28, 0xb1, 0xca, 0x1a, 0xf2, 0xa5, 0xda, 0x19, 0x27, 0xd6, 0x5f, 0x2e, 0x80, 0xea, 0x33,
0x36, 0x2a, 0x6b, 0x58, 0x6d, 0x0a, 0xdf, 0x02, 0x93, 0xf8, 0xdd, 0xad, 0x9d, 0x87, 0xda, 0xab,
0xbc, 0xf4, 0xea, 0x64, 0x6e, 0xaf, 0x4a, 0xfb, 0x87, 0xc7, 0x5b, 0x3b, 0x0f, 0x53, 0xa7, 0x6e,
0xe9, 0x57, 0x9d, 0x82, 0xb6, 0x51, 0x49, 0x89, 0xca, 0xa3, 0x43, 0xa0, 0xc5, 0x56, 0x07, 0xb3,
0x4e, 0x75, 0x51, 0xf2, 0xae, 0x8f, 0x12, 0x0b, 0x28, 0xa4, 0x03, 0xcc, 0x3a, 0xe7, 0xef, 0xd3,
0x1e, 0x7e, 0x8e, 0x23, 0xee, 0xf7, 0xc2, 0x14, 0x0b, 0xa8, 0xc3, 0xc2, 0x6a, 0xe2, 0xc3, 0x8e,
0xf6, 0xa1, 0x70, 0x23, 0x1f, 0x76, 0xae, 0xf2, 0x61, 0x67, 0xd6, 0x07, 0x65, 0x33, 0x21, 0xde,
0xd5, 0xc4, 0x4b, 0x37, 0x22, 0xde, 0xbd, 0x8a, 0x78, 0x77, 0x96, 0x58, 0xd9, 0x88, 0x02, 0xb8,
0x10, 0x91, 0xaa, 0x71, 0xb3, 0x02, 0xb8, 0x14, 0xe0, 0xf2, 0x44, 0xa3, 0x28, 0xbf, 0xcc, 0x80,
0x55, 0x87, 0x46, 0x8c, 0x0b, 0x65, 0x44, 0xbb, 0x01, 0xd1, 0xc4, 0x45, 0x49, 0xfc, 0x62, 0x6e,
0xe2, 0xbb, 0x8a, 0xf8, 0x2a, 0x4c, 0x1b, 0xdd, 0x9a, 0x55, 0xab, 0x2b, 0x70, 0x50, 0xe9, 0x12,
0x4e, 0x62, 0xd6, 0xee, 0xc5, 0x9e, 0x66, 0x07, 0x92, 0xfd, 0x70, 0x6e, 0x76, 0x5d, 0x20, 0x17,
0xf1, 0x6c, 0xb4, 0x72, 0xae, 0x52, 0xac, 0x11, 0x28, 0xfb, 0xe2, 0x2a, 0xed, 0x5e, 0xa0, 0x39,
0x4b, 0x92, 0xf3, 0xd9, 0xdc, 0x9c, 0xba, 0xd2, 0x67, 0xd1, 0x6c, 0xb4, 0x9c, 0x2a, 0x14, 0xdf,
0x10, 0xc0, 0xb0, 0xe7, 0xc7, 0x2d, 0x2f, 0xc0, 0x8e, 0x4f, 0x62, 0xcd, 0x69, 0x4a, 0xce, 0xe7,
0x73, 0x73, 0xde, 0x56, 0x9c, 0x97, 0x11, 0x6d, 0x54, 0x11, 0xca, 0x67, 0x4a, 0xa7, 0xa8, 0x3b,
0xc0, 0x6c, 0x93, 0x38, 0xf0, 0x23, 0x4d, 0xba, 0x2c, 0x49, 0xf7, 0xe7, 0x26, 0xd5, 0x09, 0x3c,
0x8d, 0x65, 0xa3, 0x92, 0x12, 0x15, 0xd3, 0xa7, 0x60, 0x79, 0x48, 0x03, 0xda, 0xea, 0x3f, 0xd2,
0x54, 0x65, 0x49, 0xf5, 0x74, 0x6e, 0x2a, 0x3d, 0xc0, 0x66, 0xc0, 0x6c, 0x54, 0x12, 0xf2, 0xab,
0x47, 0x8a, 0x8b, 0x81, 0x12, 0x79, 0x8b, 0x59, 0x5a, 0x28, 0x2b, 0x92, 0x09, 0xcd, 0x5d, 0xa4,
0x60, 0xff, 0x75, 0xe3, 0xe5, 0x8b, 0xb4, 0x46, 0xd3, 0xd9, 0x77, 0x0e, 0x2c, 0x7a, 0x92, 0x90,
0x26, 0x59, 0xe3, 0x60, 0x8e, 0x83, 0x21, 0xe3, 0x9a, 0xb7, 0x72, 0xb3, 0xac, 0x99, 0x45, 0xb3,
0xd1, 0x72, 0xaa, 0x90, 0x7c, 0xf6, 0x26, 0x58, 0x7c, 0xc9, 0xc5, 0xb4, 0xae, 0x80, 0xdc, 0x29,
0x19, 0xaa, 0x79, 0x88, 0xc4, 0x12, 0xae, 0x82, 0xc5, 0x3e, 0x0e, 0x7a, 0x6a, 0xec, 0x17, 0x91,
0x12, 0xec, 0x57, 0x60, 0xe5, 0x24, 0xc6, 0x11, 0xc3, 0x0e, 0xf7, 0x69, 0x74, 0x44, 0x3d, 0x06,
0x21, 0xc8, 0xcb, 0x5e, 0xac, 0xce, 0xca, 0x35, 0xdc, 0x04, 0xf9, 0x80, 0x7a, 0xac, 0x9a, 0xad,
0xe7, 0xd6, 0x4b, 0xdb, 0x77, 0x37, 0xae, 0xfe, 0x6c, 0xd9, 0x38, 0xa2, 0x1e, 0x92, 0x86, 0xf6,
0xf7, 0x59, 0x90, 0x3b, 0xa2, 0x1e, 0xac, 0x82, 0x25, 0xec, 0xba, 0x31, 0x61, 0x4c, 0xe3, 0xa5,
0x22, 0x5c, 0x03, 0x05, 0x4e, 0xbb, 0xbe, 0xa3, 0x40, 0x8b, 0x48, 0x4b, 0x82, 0xde, 0xc5, 0x1c,
0xcb, 0xb9, 0x66, 0x22, 0xb9, 0x86, 0xdb, 0xc0, 0x94, 0xfe, 0xb6, 0xa2, 0x5e, 0xd8, 0x26, 0xb1,
0x1c, 0x4f, 0xf9, 0xe6, 0xca, 0x59, 0x62, 0x95, 0xa4, 0xfe, 0x3f, 0x52, 0x8d, 0xa6, 0x05, 0x78,
0x1f, 0x2c, 0xf1, 0xc1, 0xf4, 0x54, 0xb9, 0x75, 0x96, 0x58, 0x2b, 0xfc, 0xdc, 0x59, 0x31, 0x34,
0x50, 0x81, 0x0f, 0x0e, 0x94, 0x83, 0x06, 0x1f, 0xb4, 0xfc, 0xc8, 0x25, 0x03, 0x39, 0x38, 0xf2,
0xcd, 0xd5, 0xb3, 0xc4, 0xaa, 0x4c, 0x99, 0x1f, 0x8a, 0x3d, 0xb4, 0xc4, 0x07, 0x72, 0x01, 0xef,
0x03, 0xa0, 0xae, 0x24, 0x19, 0x54, 0xcb, 0x5f, 0x3e, 0x4b, 0xac, 0xa2, 0xd4, 0x4a, 0xec, 0xf3,
0x25, 0xb4, 0xc1, 0xa2, 0xc2, 0x36, 0x24, 0xb6, 0x79, 0x96, 0x58, 0x46, 0x40, 0x3d, 0x85, 0xa9,
0xb6, 0x44, 0xa8, 0x62, 0x12, 0xd2, 0x3e, 0x71, 0x65, 0x33, 0x35, 0x50, 0x2a, 0xda, 0xbf, 0x65,
0x40, 0xf1, 0x64, 0x80, 0x88, 0x43, 0xfc, 0x2e, 0xbf, 0xf2, 0x7d, 0x20, 0xc8, 0xbf, 0x89, 0x69,
0xa8, 0xdf, 0x56, 0xae, 0xe1, 0xf6, 0x54, 0x20, 0x4b, 0xdb, 0xb5, 0xeb, 0xde, 0xec, 0x64, 0xb0,
0x87, 0x39, 0xd6, 0x81, 0xde, 0x05, 0x85, 0x98, 0xb0, 0x5e, 0xc0, 0x65, 0x88, 0x4b, 0xdb, 0xf5,
0xeb, 0x4f, 0x21, 0x69, 0x87, 0xb4, 0xbd, 0x48, 0x2f, 0xe5, 0xa1, 0x08, 0x76, 0x3e, 0xf5, 0xe9,
0x6f, 0xe9, 0xc3, 0x75, 0x88, 0xef, 0x75, 0xb8, 0x0a, 0xad, 0x7e, 0xa7, 0x03, 0xa9, 0x82, 0x7f,
0xbd, 0x1c, 0xc8, 0xa9, 0xc8, 0x3d, 0xce, 0x7f, 0x25, 0x3e, 0xfd, 0xbe, 0xc9, 0x02, 0x23, 0xa5,
0x84, 0x4f, 0x41, 0xc5, 0xa1, 0x11, 0x8f, 0xb1, 0xc3, 0x5b, 0x33, 0xc9, 0xd5, 0xbc, 0x7b, 0xde,
0xd2, 0x2f, 0x5a, 0xd8, 0x68, 0x25, 0x55, 0x35, 0x74, 0x06, 0xae, 0x82, 0xc5, 0x76, 0x40, 0x75,
0xd4, 0x4c, 0xa4, 0x04, 0xf8, 0x7f, 0x99, 0x37, 0x32, 0xdb, 0x55, 0xe4, 0xee, 0x5d, 0x1b, 0x83,
0xd9, 0xc2, 0x69, 0xae, 0x89, 0xa2, 0x1e, 0x27, 0x56, 0x59, 0xdd, 0x40, 0xa3, 0xd8, 0x22, 0xc7,
0x64, 0x61, 0x55, 0x40, 0x2e, 0x26, 0x2a, 0xb2, 0x26, 0x12, 0x4b, 0x78, 0x07, 0x18, 0x31, 0xe9,
0x93, 0x98, 0x13, 0x57, 0xc6, 0xcd, 0x40, 0x13, 0x19, 0xde, 0x06, 0x86, 0x87, 0x59, 0xab, 0xc7,
0x88, 0xab, 0xc3, 0xb6, 0xe4, 0x61, 0xf6, 0x3f, 0x46, 0x5c, 0x1d, 0x93, 0x5f, 0xb2, 0xa0, 0xa0,
0x1e, 0x0f, 0x6e, 0x01, 0xc3, 0x11, 0x1f, 0xc6, 0x2d, 0xdf, 0x95, 0x91, 0x30, 0x9b, 0x6b, 0xa3,
0xc4, 0x5a, 0x92, 0x1f, 0xcb, 0x87, 0x7b, 0x67, 0x89, 0xb5, 0xe4, 0xa8, 0x25, 0xd2, 0x0b, 0x57,
0x38, 0x1f, 0xd1, 0xc8, 0x51, 0xed, 0x20, 0x8f, 0x94, 0x00, 0xff, 0x09, 0x8a, 0x82, 0xb4, 0x1b,
0xfb, 0x0e, 0x51, 0x15, 0xd8, 0x34, 0x47, 0x89, 0x65, 0x3c, 0xc3, 0xec, 0x58, 0xe8, 0x90, 0xb8,
0x93, 0x5c, 0xc1, 0x1a, 0xc8, 0x79, 0x98, 0xe9, 0x52, 0x4c, 0x8d, 0x8e, 0xfc, 0xd0, 0xe7, 0x48,
0x6c, 0xc0, 0x32, 0xc8, 0x72, 0xaa, 0x4a, 0x0f, 0x65, 0x39, 0x85, 0xf5, 0xb4, 0xff, 0x14, 0x24,
0x2c, 0x18, 0x25, 0x56, 0xa1, 0x11, 0xd2, 0x5e, 0xc4, 0x75, 0x2f, 0x52, 0x29, 0xd4, 0xed, 0x71,
0x99, 0x04, 0x26, 0x52, 0x02, 0xc4, 0xc0, 0xc0, 0x8e, 0x43, 0x18, 0x23, 0xac, 0x6a, 0xc8, 0xf6,
0xf3, 0xf7, 0xeb, 0x1e, 0xa4, 0x21, 0xed, 0x4e, 0x7a, 0xe2, 0x53, 0xa1, 0x2e, 0x1e, 0xe3, 0x2c,
0xb1, 0x80, 0x3a, 0x7c, 0xe4, 0x33, 0xfe, 0xdd, 0x4f, 0x16, 0x68, 0x4c, 0x24, 0x34, 0x81, 0x85,
0x26, 0xc8, 0xf4, 0x65, 0xcd, 0x99, 0x28, 0xd3, 0x17, 0x52, 0x2c, 0x3f, 0x28, 0x4c, 0x94, 0x89,
0x85, 0xc4, 0xe4, 0xa8, 0x37, 0x51, 0x86, 0xe9, 0xc8, 0xdf, 0x03, 0xc5, 0xe6, 0x90, 0x13, 0x09,
0x23, 0xb3, 0x48, 0x08, 0xd5, 0x4c, 0x3d, 0x27, 0xb3, 0x48, 0x08, 0xda, 0x10, 0x83, 0xd2, 0xd4,
0x9d, 0xfe, 0xa0, 0x19, 0x6e, 0x03, 0x93, 0x71, 0x1a, 0x63, 0x8f, 0xb4, 0x4e, 0xc9, 0x50, 0xb7,
0x44, 0xd5, 0xe0, 0xb4, 0xfe, 0x39, 0x19, 0x32, 0x34, 0x2d, 0x28, 0x8a, 0x66, 0xe3, 0xfd, 0xa8,
0x96, 0xf9, 0x30, 0xaa, 0x65, 0x7e, 0x1e, 0xd5, 0x32, 0x5f, 0x7f, 0xac, 0x2d, 0x7c, 0xf8, 0x58,
0x5b, 0xf8, 0xe1, 0x63, 0x6d, 0xe1, 0x93, 0x7b, 0x97, 0x67, 0xcb, 0xf9, 0xff, 0xd1, 0x81, 0xfc,
0x47, 0x2a, 0x07, 0x4c, 0xbb, 0x20, 0xff, 0x5d, 0x3e, 0xfa, 0x3d, 0x00, 0x00, 0xff, 0xff, 0x20,
0x17, 0x75, 0x75, 0xaf, 0x0e, 0x00, 0x00,
0x01, 0x67, 0x1d, 0x60, 0x8b, 0x96, 0x0c, 0xe1, 0x04, 0x03, 0x57, 0x88, 0x96, 0x6c, 0x09, 0x96,
0x13, 0x61, 0xac, 0xd8, 0x41, 0x1a, 0x62, 0xb8, 0x3b, 0x5e, 0x6e, 0xb4, 0xbb, 0xc3, 0xec, 0x0c,
0x69, 0x32, 0x40, 0x80, 0x94, 0x29, 0x93, 0x2e, 0xa5, 0xeb, 0xfc, 0x25, 0x46, 0x2a, 0x97, 0x41,
0x8a, 0x4d, 0x40, 0x77, 0x2a, 0xd9, 0xa4, 0x09, 0x90, 0x60, 0x3e, 0x96, 0x22, 0x65, 0x29, 0x00,
0xa1, 0x8a, 0xf3, 0xde, 0xbc, 0xf9, 0xfd, 0xe6, 0xbd, 0x79, 0x1f, 0x4b, 0x50, 0x27, 0xbc, 0x43,
0xe2, 0xd0, 0x8f, 0x78, 0x83, 0xf4, 0xc3, 0x46, 0x7f, 0x13, 0x07, 0xdd, 0x0e, 0xde, 0x14, 0xc2,
0x46, 0x37, 0xa6, 0x9c, 0xc2, 0xb5, 0x89, 0xc5, 0x86, 0x50, 0xa6, 0x16, 0xb7, 0x56, 0x3d, 0xea,
0x51, 0x69, 0xd2, 0x10, 0x2b, 0x65, 0x6d, 0xff, 0x9e, 0x01, 0x85, 0x63, 0x1c, 0xe3, 0x90, 0xc1,
0x4d, 0x50, 0x24, 0xfd, 0xb0, 0xe5, 0x92, 0x88, 0x86, 0xd5, 0x4c, 0x3d, 0xb3, 0x5e, 0x6c, 0xae,
0x8e, 0x13, 0xab, 0x32, 0xc4, 0x61, 0xf0, 0xd0, 0x9e, 0x6c, 0xd9, 0xc8, 0x20, 0xfd, 0x70, 0x4f,
0x2c, 0xe1, 0xff, 0xc1, 0x32, 0x89, 0x70, 0x3b, 0x20, 0x2d, 0x27, 0x26, 0x98, 0x93, 0x6a, 0xb6,
0x9e, 0x59, 0x37, 0x9a, 0xd5, 0x71, 0x62, 0xad, 0xea, 0x63, 0xd3, 0xdb, 0x36, 0x32, 0x95, 0xfc,
0x48, 0x8a, 0xf0, 0x7f, 0xa0, 0x94, 0xee, 0xe3, 0x20, 0xa8, 0xe6, 0xe4, 0xe1, 0xb5, 0x71, 0x62,
0xc1, 0xd9, 0xc3, 0x38, 0x08, 0x6c, 0x04, 0xf4, 0x51, 0x1c, 0x04, 0x70, 0x17, 0x00, 0x32, 0xe0,
0x31, 0x6e, 0x11, 0xbf, 0xcb, 0xaa, 0xf9, 0x7a, 0x6e, 0x3d, 0xd7, 0xb4, 0x47, 0x89, 0x55, 0xdc,
0x17, 0xda, 0xfd, 0xc3, 0x63, 0x36, 0x4e, 0xac, 0xbf, 0x69, 0x90, 0x89, 0xa1, 0x8d, 0x8a, 0x52,
0xd8, 0xf7, 0xbb, 0xec, 0x61, 0xfe, 0xfb, 0x37, 0xd6, 0x82, 0xfd, 0xa6, 0x0c, 0x4a, 0x8f, 0x3a,
0xd8, 0x8f, 0x1e, 0xd1, 0xe8, 0x95, 0xef, 0xc1, 0x2f, 0xc0, 0x4a, 0x87, 0x86, 0x84, 0x71, 0x82,
0xdd, 0x56, 0x3b, 0xa0, 0xce, 0xa9, 0x8e, 0xc4, 0xc1, 0xdb, 0xc4, 0x5a, 0xf8, 0x39, 0xb1, 0xfe,
0xe3, 0xf9, 0xbc, 0xd3, 0x6b, 0x6f, 0x38, 0x34, 0x6c, 0x38, 0x94, 0x85, 0x94, 0xe9, 0x9f, 0x7b,
0xcc, 0x3d, 0x6d, 0xf0, 0x61, 0x97, 0xb0, 0x8d, 0xc3, 0x88, 0x8f, 0x13, 0x6b, 0x4d, 0xd1, 0x5f,
0x80, 0xb3, 0x51, 0x79, 0xa2, 0x69, 0x0a, 0x05, 0xfc, 0x0a, 0x94, 0x5d, 0x4c, 0x5b, 0xaf, 0x68,
0x7c, 0xaa, 0x19, 0xb3, 0x92, 0xf1, 0xe5, 0x7c, 0x8c, 0xa3, 0xc4, 0x32, 0xf7, 0x76, 0x3f, 0x7e,
0x4c, 0xe3, 0x53, 0x89, 0x3b, 0x4e, 0xac, 0xbf, 0xab, 0x1b, 0xcc, 0xa2, 0xdb, 0xc8, 0x74, 0x31,
0x9d, 0x98, 0xc1, 0x97, 0xa0, 0x32, 0x31, 0x60, 0xbd, 0x6e, 0x97, 0xc6, 0x5c, 0x3f, 0xc4, 0xbd,
0x51, 0x62, 0x95, 0x35, 0xe4, 0x73, 0xb5, 0x33, 0x4e, 0xac, 0x7f, 0x5c, 0x00, 0xd5, 0x67, 0x6c,
0x54, 0xd6, 0xb0, 0xda, 0x14, 0xbe, 0x06, 0x26, 0xf1, 0xbb, 0x9b, 0xdb, 0xf7, 0xb5, 0x57, 0x79,
0xe9, 0xd5, 0xc9, 0xdc, 0x5e, 0x95, 0xf6, 0x0f, 0x8f, 0x37, 0xb7, 0xef, 0xa7, 0x4e, 0xdd, 0xd0,
0xaf, 0x3a, 0x05, 0x6d, 0xa3, 0x92, 0x12, 0x95, 0x47, 0x87, 0x40, 0x8b, 0xad, 0x0e, 0x66, 0x9d,
0xea, 0xa2, 0xe4, 0x5d, 0x1f, 0x25, 0x16, 0x50, 0x48, 0x07, 0x98, 0x75, 0xce, 0xdf, 0xa7, 0x3d,
0xfc, 0x12, 0x47, 0xdc, 0xef, 0x85, 0x29, 0x16, 0x50, 0x87, 0x85, 0xd5, 0xc4, 0x87, 0x6d, 0xed,
0x43, 0xe1, 0x5a, 0x3e, 0x6c, 0x5f, 0xe6, 0xc3, 0xf6, 0xac, 0x0f, 0xca, 0x66, 0x42, 0xbc, 0xa3,
0x89, 0x97, 0xae, 0x45, 0xbc, 0x73, 0x19, 0xf1, 0xce, 0x2c, 0xb1, 0xb2, 0x11, 0x05, 0x70, 0x21,
0x22, 0x55, 0xe3, 0x7a, 0x05, 0xf0, 0x41, 0x80, 0xcb, 0x13, 0x8d, 0xa2, 0xfc, 0x3a, 0x03, 0x56,
0x1d, 0x1a, 0x31, 0x2e, 0x94, 0x11, 0xed, 0x06, 0x44, 0x13, 0x17, 0x25, 0xf1, 0xb3, 0xb9, 0x89,
0x6f, 0x2b, 0xe2, 0xcb, 0x30, 0x6d, 0x74, 0x63, 0x56, 0xad, 0xae, 0xc0, 0x41, 0xa5, 0x4b, 0x38,
0x89, 0x59, 0xbb, 0x17, 0x7b, 0x9a, 0x1d, 0x48, 0xf6, 0xc3, 0xb9, 0xd9, 0x75, 0x81, 0x5c, 0xc4,
0xb3, 0xd1, 0xca, 0xb9, 0x4a, 0xb1, 0x46, 0xa0, 0xec, 0x8b, 0xab, 0xb4, 0x7b, 0x81, 0xe6, 0x2c,
0x49, 0xce, 0x27, 0x73, 0x73, 0xea, 0x4a, 0x9f, 0x45, 0xb3, 0xd1, 0x72, 0xaa, 0x50, 0x7c, 0x43,
0x00, 0xc3, 0x9e, 0x1f, 0xb7, 0xbc, 0x00, 0x3b, 0x3e, 0x89, 0x35, 0xa7, 0x29, 0x39, 0x9f, 0xce,
0xcd, 0x79, 0x53, 0x71, 0x7e, 0x88, 0x68, 0xa3, 0x8a, 0x50, 0x3e, 0x51, 0x3a, 0x45, 0xdd, 0x01,
0x66, 0x9b, 0xc4, 0x81, 0x1f, 0x69, 0xd2, 0x65, 0x49, 0xba, 0x3f, 0x37, 0xa9, 0x4e, 0xe0, 0x69,
0x2c, 0x1b, 0x95, 0x94, 0xa8, 0x98, 0x3e, 0x07, 0xcb, 0x43, 0x1a, 0xd0, 0x56, 0xff, 0x81, 0xa6,
0x2a, 0x4b, 0xaa, 0xc7, 0x73, 0x53, 0xe9, 0x01, 0x36, 0x03, 0x66, 0xa3, 0x92, 0x90, 0x5f, 0x3c,
0x50, 0x5c, 0x0c, 0x94, 0xc8, 0x6b, 0xcc, 0xd2, 0x42, 0x59, 0x91, 0x4c, 0x68, 0xee, 0x22, 0x05,
0xfb, 0x2f, 0x77, 0x9f, 0x3f, 0x4b, 0x6b, 0x34, 0x9d, 0x7d, 0xe7, 0xc0, 0xa2, 0x27, 0x09, 0x69,
0x92, 0x35, 0x0e, 0xe6, 0x38, 0x18, 0x32, 0xae, 0x79, 0x2b, 0xd7, 0xcb, 0x9a, 0x59, 0x34, 0x1b,
0x2d, 0xa7, 0x0a, 0xc9, 0x67, 0x37, 0xc0, 0xe2, 0x73, 0x2e, 0xa6, 0x75, 0x05, 0xe4, 0x4e, 0xc9,
0x50, 0xcd, 0x43, 0x24, 0x96, 0x70, 0x15, 0x2c, 0xf6, 0x71, 0xd0, 0x53, 0x63, 0xbf, 0x88, 0x94,
0x60, 0xbf, 0x00, 0x2b, 0x27, 0x31, 0x8e, 0x18, 0x76, 0xb8, 0x4f, 0xa3, 0x23, 0xea, 0x31, 0x08,
0x41, 0x5e, 0xf6, 0x62, 0x75, 0x56, 0xae, 0x61, 0x03, 0xe4, 0x03, 0xea, 0xb1, 0x6a, 0xb6, 0x9e,
0x5b, 0x2f, 0x6d, 0xdd, 0xde, 0xb8, 0xfc, 0xb3, 0x65, 0xe3, 0x88, 0x7a, 0x48, 0x1a, 0xda, 0x3f,
0x66, 0x41, 0xee, 0x88, 0x7a, 0xb0, 0x0a, 0x96, 0xb0, 0xeb, 0xc6, 0x84, 0x31, 0x8d, 0x97, 0x8a,
0x70, 0x0d, 0x14, 0x38, 0xed, 0xfa, 0x8e, 0x02, 0x2d, 0x22, 0x2d, 0x09, 0x7a, 0x17, 0x73, 0x2c,
0xe7, 0x9a, 0x89, 0xe4, 0x1a, 0x6e, 0x01, 0x53, 0xfa, 0xdb, 0x8a, 0x7a, 0x61, 0x9b, 0xc4, 0x72,
0x3c, 0xe5, 0x9b, 0x2b, 0x67, 0x89, 0x55, 0x92, 0xfa, 0x8f, 0xa4, 0x1a, 0x4d, 0x0b, 0xf0, 0x2e,
0x58, 0xe2, 0x83, 0xe9, 0xa9, 0x72, 0xe3, 0x2c, 0xb1, 0x56, 0xf8, 0xb9, 0xb3, 0x62, 0x68, 0xa0,
0x02, 0x1f, 0x1c, 0x28, 0x07, 0x0d, 0x3e, 0x68, 0xf9, 0x91, 0x4b, 0x06, 0x72, 0x70, 0xe4, 0x9b,
0xab, 0x67, 0x89, 0x55, 0x99, 0x32, 0x3f, 0x14, 0x7b, 0x68, 0x89, 0x0f, 0xe4, 0x02, 0xde, 0x05,
0x40, 0x5d, 0x49, 0x32, 0xa8, 0x96, 0xbf, 0x7c, 0x96, 0x58, 0x45, 0xa9, 0x95, 0xd8, 0xe7, 0x4b,
0x68, 0x83, 0x45, 0x85, 0x6d, 0x48, 0x6c, 0xf3, 0x2c, 0xb1, 0x8c, 0x80, 0x7a, 0x0a, 0x53, 0x6d,
0x89, 0x50, 0xc5, 0x24, 0xa4, 0x7d, 0xe2, 0xca, 0x66, 0x6a, 0xa0, 0x54, 0xb4, 0xff, 0xc8, 0x80,
0xe2, 0xc9, 0x00, 0x11, 0x87, 0xf8, 0x5d, 0x7e, 0xe9, 0xfb, 0x40, 0x90, 0x7f, 0x15, 0xd3, 0x50,
0xbf, 0xad, 0x5c, 0xc3, 0xad, 0xa9, 0x40, 0x96, 0xb6, 0x6a, 0x57, 0xbd, 0xd9, 0xc9, 0x60, 0x0f,
0x73, 0xac, 0x03, 0xbd, 0x03, 0x0a, 0x31, 0x61, 0xbd, 0x80, 0xcb, 0x10, 0x97, 0xb6, 0xea, 0x57,
0x9f, 0x42, 0xd2, 0x0e, 0x69, 0x7b, 0x91, 0x5e, 0xca, 0x43, 0x11, 0xec, 0x7c, 0xea, 0xd3, 0xbf,
0xd2, 0x87, 0xeb, 0x10, 0xdf, 0xeb, 0x70, 0x15, 0x5a, 0xfd, 0x4e, 0x07, 0x52, 0x05, 0xff, 0xf9,
0x61, 0x20, 0xa7, 0x22, 0xf7, 0x30, 0xff, 0x8d, 0xf8, 0xf4, 0xfb, 0x2e, 0x0b, 0x8c, 0x94, 0x12,
0x3e, 0x06, 0x15, 0x87, 0x46, 0x3c, 0xc6, 0x0e, 0x6f, 0xcd, 0x24, 0x57, 0xf3, 0xf6, 0x79, 0x4b,
0xbf, 0x68, 0x61, 0xa3, 0x95, 0x54, 0xb5, 0xab, 0x33, 0x70, 0x15, 0x2c, 0xb6, 0x03, 0xaa, 0xa3,
0x66, 0x22, 0x25, 0xc0, 0x4f, 0x65, 0xde, 0xc8, 0x6c, 0x57, 0x91, 0xbb, 0x73, 0x65, 0x0c, 0x66,
0x0b, 0xa7, 0xb9, 0x26, 0x8a, 0x7a, 0x9c, 0x58, 0x65, 0x75, 0x03, 0x8d, 0x62, 0x8b, 0x1c, 0x93,
0x85, 0x55, 0x01, 0xb9, 0x98, 0xa8, 0xc8, 0x9a, 0x48, 0x2c, 0xe1, 0x2d, 0x60, 0xc4, 0xa4, 0x4f,
0x62, 0x4e, 0x5c, 0x19, 0x37, 0x03, 0x4d, 0x64, 0x78, 0x13, 0x18, 0x1e, 0x66, 0xad, 0x1e, 0x23,
0xae, 0x0e, 0xdb, 0x92, 0x87, 0xd9, 0x27, 0x8c, 0xb8, 0x3a, 0x26, 0xbf, 0x65, 0x41, 0x41, 0x3d,
0x1e, 0xdc, 0x04, 0x86, 0x23, 0x3e, 0x8c, 0x5b, 0xbe, 0x2b, 0x23, 0x61, 0x36, 0xd7, 0x46, 0x89,
0xb5, 0x24, 0x3f, 0x96, 0x0f, 0xf7, 0xce, 0x12, 0x6b, 0xc9, 0x51, 0x4b, 0xa4, 0x17, 0xae, 0x70,
0x3e, 0xa2, 0x91, 0xa3, 0xda, 0x41, 0x1e, 0x29, 0x01, 0xfe, 0x17, 0x14, 0x05, 0x69, 0x37, 0xf6,
0x1d, 0xa2, 0x2a, 0xb0, 0x69, 0x8e, 0x12, 0xcb, 0x78, 0x82, 0xd9, 0xb1, 0xd0, 0x21, 0x71, 0x27,
0xb9, 0x82, 0x35, 0x90, 0xf3, 0x30, 0xd3, 0xa5, 0x98, 0x1a, 0x1d, 0xf9, 0xa1, 0xcf, 0x91, 0xd8,
0x80, 0x65, 0x90, 0xe5, 0x54, 0x95, 0x1e, 0xca, 0x72, 0x0a, 0xeb, 0x69, 0xff, 0x29, 0x48, 0x58,
0x30, 0x4a, 0xac, 0xc2, 0x6e, 0x48, 0x7b, 0x11, 0xd7, 0xbd, 0x48, 0xa5, 0x50, 0xb7, 0xc7, 0x65,
0x12, 0x98, 0x48, 0x09, 0x10, 0x03, 0x03, 0x3b, 0x0e, 0x61, 0x8c, 0xb0, 0xaa, 0x21, 0xdb, 0xcf,
0xbf, 0xaf, 0x7a, 0x90, 0x5d, 0x69, 0x77, 0xd2, 0x13, 0x9f, 0x0a, 0x75, 0xf1, 0x18, 0x67, 0x89,
0x05, 0xd4, 0xe1, 0x23, 0x9f, 0xf1, 0x1f, 0x7e, 0xb1, 0xc0, 0xee, 0x44, 0x42, 0x13, 0x58, 0x68,
0x82, 0x4c, 0x5f, 0xd6, 0x9c, 0x89, 0x32, 0x7d, 0x21, 0xc5, 0xf2, 0x83, 0xc2, 0x44, 0x99, 0x58,
0x48, 0x4c, 0x8e, 0x7a, 0x13, 0x65, 0x98, 0x8e, 0xfc, 0x1d, 0x50, 0x6c, 0x0e, 0x39, 0x91, 0x30,
0x32, 0x8b, 0x84, 0x50, 0xcd, 0xd4, 0x73, 0x32, 0x8b, 0x84, 0xa0, 0x0d, 0x31, 0x28, 0x4d, 0xdd,
0xe9, 0x2f, 0x9a, 0xe1, 0x16, 0x30, 0x19, 0xa7, 0x31, 0xf6, 0x48, 0xeb, 0x94, 0x0c, 0x75, 0x4b,
0x54, 0x0d, 0x4e, 0xeb, 0x9f, 0x92, 0x21, 0x43, 0xd3, 0x82, 0xa2, 0x68, 0x36, 0xdf, 0x8e, 0x6a,
0x99, 0x77, 0xa3, 0x5a, 0xe6, 0xd7, 0x51, 0x2d, 0xf3, 0xed, 0xfb, 0xda, 0xc2, 0xbb, 0xf7, 0xb5,
0x85, 0x9f, 0xde, 0xd7, 0x16, 0x3e, 0x5b, 0x9f, 0x9a, 0x2d, 0xbc, 0x83, 0x63, 0xe6, 0xb3, 0xc6,
0xf9, 0x1f, 0xd2, 0x81, 0xfc, 0x4b, 0x2a, 0x27, 0x4c, 0xbb, 0x20, 0xff, 0x5e, 0x3e, 0xf8, 0x33,
0x00, 0x00, 0xff, 0xff, 0x9f, 0xa0, 0x05, 0x1a, 0xb0, 0x0e, 0x00, 0x00,
}
func (m *Params) Marshal() (dAtA []byte, err error) {

View File

@ -171,33 +171,33 @@ func init() {
}
var fileDescriptor_8205a12b97b89a87 = []byte{
// 405 bytes of a gzipped FileDescriptorProto
// 406 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x92, 0xb1, 0x8e, 0xda, 0x30,
0x18, 0xc7, 0x13, 0x40, 0x04, 0x0c, 0x2a, 0x92, 0x5b, 0xb5, 0x11, 0x55, 0x03, 0x4a, 0xab, 0xc2,
0x94, 0x08, 0xba, 0x55, 0x5d, 0x08, 0x43, 0x19, 0x3a, 0x54, 0xa1, 0x53, 0x3b, 0x20, 0x63, 0x5c,
0x27, 0x12, 0x89, 0xa3, 0xd8, 0x20, 0x78, 0x83, 0x1b, 0xef, 0x39, 0xee, 0x49, 0x18, 0x19, 0x99,
0xb8, 0x13, 0xbc, 0xc1, 0x3d, 0xc1, 0x29, 0x4e, 0x02, 0x77, 0xd2, 0x65, 0x73, 0xa4, 0xdf, 0xff,
0xe7, 0x7f, 0x3e, 0x7f, 0xe0, 0x0b, 0x11, 0x1e, 0x89, 0x03, 0x3f, 0x14, 0x36, 0x59, 0x07, 0xf6,
0x7a, 0x80, 0x96, 0x91, 0x87, 0x06, 0x36, 0x25, 0x21, 0xe1, 0x3e, 0xb7, 0xa2, 0x98, 0x09, 0x06,
0xdf, 0x5f, 0x28, 0x8b, 0xac, 0x03, 0x2b, 0xa7, 0xda, 0xef, 0x28, 0xa3, 0x4c, 0x22, 0x76, 0x72,
0x4a, 0xe9, 0x76, 0xb7, 0xc0, 0x99, 0x44, 0x25, 0x61, 0x1e, 0x4a, 0xa0, 0xf9, 0x33, 0xbd, 0x61,
0x2a, 0x90, 0x20, 0x70, 0x02, 0x6a, 0x08, 0x63, 0xb6, 0x0a, 0x05, 0xd7, 0xd5, 0x6e, 0xb9, 0xdf,
0x18, 0x7e, 0xb5, 0x5e, 0xbf, 0xd3, 0xca, 0x72, 0xa3, 0x14, 0x77, 0x2a, 0xbb, 0x63, 0x47, 0x71,
0x2f, 0x69, 0x88, 0x41, 0x13, 0x7b, 0xc8, 0x0f, 0x67, 0x98, 0x85, 0xff, 0x7d, 0xaa, 0x97, 0xba,
0x6a, 0xbf, 0x31, 0xfc, 0x5c, 0x64, 0x1b, 0x27, 0xec, 0x58, 0xa2, 0xce, 0xc7, 0x44, 0xf5, 0x78,
0xec, 0xbc, 0xdd, 0xa2, 0x60, 0xf9, 0xdd, 0x7c, 0xae, 0x31, 0xdd, 0x06, 0xbe, 0x92, 0xf0, 0x07,
0xa8, 0x46, 0x28, 0x46, 0x01, 0xd7, 0xcb, 0x52, 0x6f, 0x14, 0xe9, 0x7f, 0x4b, 0x2a, 0x2b, 0x99,
0x65, 0xe0, 0x3f, 0x50, 0x13, 0x1b, 0x3e, 0x5b, 0x32, 0xca, 0xf5, 0x8a, 0xfc, 0xd9, 0x5e, 0x51,
0xfe, 0x4f, 0x8c, 0x42, 0x8e, 0xb0, 0xf0, 0x59, 0xf8, 0x8b, 0x51, 0xee, 0x7c, 0xc8, 0x2a, 0xb6,
0xd2, 0x8a, 0xb9, 0xc6, 0x74, 0x35, 0xb1, 0xe1, 0x09, 0x61, 0xde, 0xa8, 0xe0, 0xcd, 0xcb, 0x11,
0x41, 0x1d, 0x68, 0x68, 0xb1, 0x88, 0x09, 0x4f, 0x66, 0xab, 0xf6, 0xeb, 0x6e, 0xfe, 0x09, 0x21,
0xa8, 0x60, 0xb6, 0x20, 0x72, 0x48, 0x75, 0x57, 0x9e, 0xe1, 0x04, 0x68, 0x5c, 0xb0, 0x18, 0x51,
0xa2, 0x97, 0x65, 0xb9, 0x4f, 0x45, 0xe5, 0xe4, 0xd3, 0x39, 0xad, 0xa4, 0xd2, 0xdd, 0x7d, 0x47,
0x9b, 0xa6, 0x29, 0x37, 0x8f, 0x3b, 0xa3, 0xdd, 0xc9, 0x50, 0xf7, 0x27, 0x43, 0x7d, 0x38, 0x19,
0xea, 0xed, 0xd9, 0x50, 0xf6, 0x67, 0x43, 0x39, 0x9c, 0x0d, 0xe5, 0x6f, 0x8f, 0xfa, 0xc2, 0x5b,
0xcd, 0x2d, 0xcc, 0x02, 0x1b, 0x33, 0x1e, 0x30, 0x6e, 0x5f, 0x77, 0x66, 0x23, 0xb7, 0x46, 0x6c,
0x23, 0xc2, 0xe7, 0x55, 0xb9, 0x2f, 0xdf, 0x9e, 0x02, 0x00, 0x00, 0xff, 0xff, 0xf3, 0x74, 0xbc,
0x46, 0xa7, 0x02, 0x00, 0x00,
0x18, 0xc7, 0x13, 0x40, 0x04, 0x0c, 0x2a, 0x92, 0x5b, 0xb5, 0x11, 0x55, 0x03, 0x4a, 0xab, 0x36,
0x53, 0x22, 0xe8, 0x56, 0x75, 0x69, 0x18, 0xca, 0xd0, 0xa1, 0x0a, 0x9d, 0x7a, 0x03, 0x32, 0xc6,
0xe7, 0x44, 0x22, 0x71, 0x14, 0x1b, 0x04, 0x6f, 0x70, 0xe3, 0x3d, 0xc7, 0x3d, 0x09, 0x23, 0x23,
0x13, 0x77, 0x82, 0x37, 0xb8, 0x27, 0x38, 0xc5, 0x49, 0xe0, 0x4e, 0xba, 0x6c, 0x8e, 0xf4, 0xfb,
0xff, 0xfc, 0xcf, 0xe7, 0x0f, 0x7c, 0x21, 0xc2, 0x27, 0x49, 0x18, 0x44, 0xc2, 0x21, 0xab, 0xd0,
0x59, 0x0d, 0xd0, 0x22, 0xf6, 0xd1, 0xc0, 0xa1, 0x24, 0x22, 0x3c, 0xe0, 0x76, 0x9c, 0x30, 0xc1,
0xe0, 0xfb, 0x33, 0x65, 0x93, 0x55, 0x68, 0x17, 0x54, 0xf7, 0x1d, 0x65, 0x94, 0x49, 0xc4, 0x49,
0x4f, 0x19, 0xdd, 0xed, 0x97, 0x38, 0xd3, 0xa8, 0x24, 0xcc, 0x7d, 0x05, 0xb4, 0x7f, 0x67, 0x37,
0x4c, 0x04, 0x12, 0x04, 0x8e, 0x41, 0x03, 0x61, 0xcc, 0x96, 0x91, 0xe0, 0xba, 0xda, 0xaf, 0x5a,
0xad, 0xe1, 0x57, 0xfb, 0xf5, 0x3b, 0xed, 0x3c, 0xf7, 0x2b, 0xc3, 0xdd, 0xda, 0xf6, 0xd0, 0x53,
0xbc, 0x73, 0x1a, 0x62, 0xd0, 0xc6, 0x3e, 0x0a, 0xa2, 0x29, 0x66, 0xd1, 0x75, 0x40, 0xf5, 0x4a,
0x5f, 0xb5, 0x5a, 0xc3, 0xcf, 0x65, 0xb6, 0x51, 0xca, 0x8e, 0x24, 0xea, 0x7e, 0x4c, 0x55, 0x8f,
0x87, 0xde, 0xdb, 0x0d, 0x0a, 0x17, 0x3f, 0xcc, 0xe7, 0x1a, 0xd3, 0x6b, 0xe1, 0x0b, 0x09, 0x7f,
0x82, 0x7a, 0x8c, 0x12, 0x14, 0x72, 0xbd, 0x2a, 0xf5, 0x46, 0x99, 0xfe, 0xaf, 0xa4, 0xf2, 0x92,
0x79, 0x06, 0x5e, 0x81, 0x86, 0x58, 0xf3, 0xe9, 0x82, 0x51, 0xae, 0xd7, 0xe4, 0xcf, 0x7e, 0x2b,
0xcb, 0xff, 0x4b, 0x50, 0xc4, 0x11, 0x16, 0x01, 0x8b, 0xfe, 0x30, 0xca, 0xdd, 0x0f, 0x79, 0xc5,
0x4e, 0x56, 0xb1, 0xd0, 0x98, 0x9e, 0x26, 0xd6, 0x3c, 0x25, 0xcc, 0x1b, 0x15, 0xbc, 0x79, 0x39,
0x22, 0xa8, 0x03, 0x0d, 0xcd, 0xe7, 0x09, 0xe1, 0xe9, 0x6c, 0x55, 0xab, 0xe9, 0x15, 0x9f, 0x10,
0x82, 0x1a, 0x66, 0x73, 0x22, 0x87, 0xd4, 0xf4, 0xe4, 0x19, 0x8e, 0x81, 0xc6, 0x05, 0x4b, 0x10,
0x25, 0x7a, 0x55, 0x96, 0xfb, 0x54, 0x56, 0x4e, 0x3e, 0x9d, 0xdb, 0x49, 0x2b, 0xdd, 0xdd, 0xf7,
0xb4, 0x49, 0x96, 0xf2, 0x8a, 0xb8, 0xeb, 0x6e, 0x8f, 0x86, 0xba, 0x3b, 0x1a, 0xea, 0xc3, 0xd1,
0x50, 0x6f, 0x4f, 0x86, 0xb2, 0x3b, 0x19, 0xca, 0xfe, 0x64, 0x28, 0xff, 0x2d, 0x1a, 0x08, 0x7f,
0x39, 0xb3, 0x31, 0x0b, 0x1d, 0xe1, 0xa3, 0x84, 0x07, 0xdc, 0xb9, 0x2c, 0xcd, 0x5a, 0xae, 0x8d,
0xd8, 0xc4, 0x84, 0xcf, 0xea, 0x72, 0x61, 0xbe, 0x3f, 0x05, 0x00, 0x00, 0xff, 0xff, 0x92, 0xea,
0xec, 0x05, 0xa8, 0x02, 0x00, 0x00,
}
func (m *GenesisState) Marshal() (dAtA []byte, err error) {

View File

@ -1077,77 +1077,77 @@ func init() {
}
var fileDescriptor_8bbc79ec2b6c5cb2 = []byte{
// 1113 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x97, 0xcf, 0x6f, 0x1b, 0x45,
0x14, 0xc7, 0xbd, 0x8d, 0xf3, 0xeb, 0x25, 0x81, 0x30, 0x98, 0x12, 0xb6, 0xc5, 0x09, 0x83, 0x1a,
0x3b, 0x3f, 0xba, 0x5b, 0x9b, 0x5f, 0xa5, 0x42, 0x82, 0xa4, 0x52, 0xa8, 0xd4, 0x0a, 0x15, 0xa7,
0xe2, 0xc0, 0xc5, 0x1a, 0xaf, 0x57, 0x6b, 0x2b, 0xeb, 0x1d, 0xd7, 0xbb, 0xb6, 0x12, 0x45, 0xb9,
0x70, 0x40, 0x20, 0x38, 0x80, 0x38, 0x80, 0x90, 0x90, 0x7a, 0xe5, 0xc6, 0xbf, 0xc0, 0xad, 0xc7,
0x4a, 0x5c, 0x38, 0x20, 0x84, 0x12, 0x0e, 0xfc, 0x19, 0x68, 0x66, 0xde, 0xda, 0xbb, 0xb6, 0xd7,
0xeb, 0x20, 0x6e, 0x33, 0xb3, 0xef, 0xc7, 0xe7, 0xbd, 0x79, 0x9e, 0xaf, 0x0c, 0xd4, 0x0e, 0x1a,
0x76, 0xa7, 0xd5, 0xf4, 0x02, 0xd3, 0xee, 0xb5, 0xcc, 0x5e, 0x89, 0xb9, 0xed, 0x06, 0x2b, 0x99,
0x8f, 0xbb, 0x76, 0xe7, 0xc4, 0x68, 0x77, 0x78, 0xc0, 0xc9, 0xd5, 0xbe, 0x8d, 0x61, 0xf7, 0x5a,
0x46, 0x68, 0xa3, 0xe7, 0x1c, 0xee, 0x70, 0x69, 0x62, 0x8a, 0x95, 0xb2, 0xd6, 0xb7, 0x2d, 0xee,
0xb7, 0xb8, 0x6f, 0xd6, 0x98, 0x6f, 0xab, 0x30, 0x66, 0xaf, 0x54, 0xb3, 0x03, 0x56, 0x32, 0xdb,
0xcc, 0x69, 0x7a, 0x2c, 0x68, 0x72, 0x0f, 0x6d, 0xaf, 0x3b, 0x9c, 0x3b, 0xae, 0x6d, 0xb2, 0x76,
0xd3, 0x64, 0x9e, 0xc7, 0x03, 0xf9, 0xd1, 0xc7, 0xaf, 0x1b, 0x09, 0x6c, 0x02, 0x42, 0x5a, 0xd0,
0x77, 0xe1, 0xc5, 0x8f, 0x45, 0x86, 0x3d, 0xcb, 0xe2, 0x5d, 0x2f, 0xa8, 0xd8, 0x8f, 0xbb, 0xb6,
0x1f, 0x90, 0x35, 0x98, 0x67, 0xf5, 0x7a, 0xc7, 0xf6, 0xfd, 0x35, 0x6d, 0x43, 0x2b, 0x2e, 0x56,
0xc2, 0xed, 0x9d, 0x85, 0x2f, 0x9e, 0xac, 0x67, 0xfe, 0x79, 0xb2, 0x9e, 0xa1, 0x16, 0xe4, 0xe2,
0xae, 0x7e, 0x9b, 0x7b, 0xbe, 0x2d, 0x7c, 0x6b, 0xcc, 0x65, 0x9e, 0x65, 0x87, 0xbe, 0xb8, 0x25,
0xd7, 0x60, 0xd1, 0xe2, 0x75, 0xbb, 0xda, 0x60, 0x7e, 0x63, 0xed, 0x8a, 0xfc, 0xb6, 0x20, 0x0e,
0xee, 0x31, 0xbf, 0x41, 0x72, 0x30, 0xeb, 0x71, 0xe1, 0x34, 0xb3, 0xa1, 0x15, 0xb3, 0x15, 0xb5,
0xa1, 0xef, 0xc3, 0x2b, 0x32, 0xc9, 0x5d, 0xd9, 0x92, 0xff, 0x40, 0xf9, 0xb9, 0x06, 0xfa, 0xb8,
0x08, 0x08, 0x7b, 0x03, 0x9e, 0x53, 0xdd, 0xae, 0xc6, 0x23, 0xad, 0xa8, 0xd3, 0x3d, 0x75, 0x48,
0x74, 0x58, 0xf0, 0x45, 0x52, 0xc1, 0x77, 0x45, 0xf2, 0xf5, 0xf7, 0x22, 0x04, 0x53, 0x51, 0xab,
0x5e, 0xb7, 0x55, 0xb3, 0x3b, 0x58, 0xc1, 0x0a, 0x9e, 0x7e, 0x24, 0x0f, 0xe9, 0x7d, 0xb8, 0x2e,
0x39, 0x3e, 0x61, 0x6e, 0xb3, 0xce, 0x02, 0xde, 0x19, 0x2a, 0xe6, 0x35, 0x58, 0xb6, 0xb8, 0x37,
0xcc, 0xb1, 0x24, 0xce, 0xf6, 0x46, 0xaa, 0xfa, 0x4a, 0x83, 0x57, 0x13, 0xa2, 0x61, 0x61, 0x05,
0x78, 0x3e, 0xa4, 0x8a, 0x47, 0x0c, 0x61, 0xff, 0xc7, 0xd2, 0xc2, 0x21, 0xda, 0x57, 0xf7, 0x7c,
0x99, 0xeb, 0xb9, 0x85, 0x43, 0xd4, 0x77, 0x4d, 0x1b, 0x22, 0x7a, 0x1f, 0x93, 0x1d, 0x06, 0xbc,
0xc3, 0x9c, 0xf4, 0x64, 0x64, 0x15, 0x66, 0x8e, 0xec, 0x13, 0x9c, 0x37, 0xb1, 0x8c, 0xa4, 0xdf,
0xc5, 0xf4, 0xfd, 0x60, 0x98, 0x3e, 0x07, 0xb3, 0x3d, 0xe6, 0x76, 0xc3, 0xe4, 0x6a, 0x43, 0xdf,
0x86, 0x55, 0x1c, 0xa5, 0xfa, 0xa5, 0x8a, 0x2c, 0xc0, 0x0b, 0x11, 0x3f, 0x4c, 0x41, 0x20, 0x2b,
0x66, 0x5f, 0x7a, 0x2d, 0x57, 0xe4, 0x9a, 0x96, 0x81, 0x48, 0xc3, 0x47, 0xc7, 0x0f, 0xb8, 0xe3,
0x87, 0x29, 0x08, 0x64, 0xe5, 0x2f, 0x46, 0xc5, 0x97, 0xeb, 0x48, 0xf0, 0x03, 0xec, 0x47, 0xe8,
0x83, 0xe1, 0x4d, 0xc8, 0xba, 0xdc, 0x11, 0x50, 0x33, 0xc5, 0xa5, 0xf2, 0x35, 0x63, 0xfc, 0x0b,
0x64, 0x3c, 0xe0, 0x4e, 0x45, 0x1a, 0xd2, 0x33, 0x78, 0x49, 0xdd, 0x84, 0xcb, 0xad, 0xa3, 0x94,
0xf4, 0xe4, 0x00, 0x60, 0xf0, 0x14, 0xc9, 0xd6, 0x2e, 0x95, 0x37, 0x0d, 0xf5, 0x9b, 0x31, 0xc4,
0xbb, 0x65, 0xa8, 0xe7, 0x0f, 0xdf, 0x2d, 0xe3, 0xe1, 0xe0, 0xa6, 0x2a, 0x11, 0xcf, 0x48, 0x19,
0x3f, 0x6b, 0x70, 0x75, 0x38, 0x3f, 0x96, 0x72, 0x00, 0xf3, 0xc1, 0x71, 0x35, 0x52, 0x4d, 0x21,
0xa9, 0x9a, 0x47, 0x1d, 0xe6, 0xf9, 0xcc, 0x12, 0xa1, 0x45, 0x84, 0xfd, 0xec, 0xd3, 0x3f, 0xd7,
0x33, 0x95, 0xb9, 0x40, 0xb6, 0x86, 0x7c, 0x38, 0x06, 0xba, 0x90, 0x0a, 0xad, 0x20, 0xa2, 0xd4,
0x74, 0x2d, 0x8a, 0xba, 0xef, 0x72, 0xde, 0xc2, 0xda, 0xa8, 0x09, 0x2f, 0x8f, 0x7c, 0x19, 0x8c,
0x54, 0x4d, 0x1c, 0xe0, 0x85, 0xab, 0x0d, 0xcd, 0xe1, 0x8d, 0x3f, 0x64, 0x1d, 0xd6, 0x0a, 0x5b,
0x4e, 0x0f, 0xf1, 0x4e, 0xc3, 0x53, 0x0c, 0xf1, 0x1e, 0xcc, 0xb5, 0xe5, 0x89, 0x8c, 0xb1, 0x54,
0xce, 0x27, 0xf5, 0x41, 0xf9, 0x85, 0xe5, 0x2b, 0x1f, 0x7a, 0x0f, 0xa9, 0x0f, 0x85, 0x46, 0x58,
0x77, 0x99, 0xeb, 0xa6, 0xff, 0x76, 0x72, 0x30, 0xdb, 0xf4, 0xda, 0xdd, 0x40, 0x76, 0x6b, 0xb9,
0xa2, 0x36, 0xf4, 0x26, 0x56, 0x19, 0x8d, 0x34, 0x98, 0xea, 0x3a, 0x0b, 0x58, 0x38, 0xd5, 0x62,
0x5d, 0xfe, 0x63, 0x05, 0x66, 0xa5, 0x3d, 0xf9, 0x5e, 0x83, 0x79, 0x7c, 0xa8, 0xc8, 0x4e, 0x12,
0xfc, 0x18, 0x3d, 0xd2, 0x77, 0xa7, 0x33, 0x56, 0x10, 0xb4, 0xf4, 0xd9, 0x6f, 0x7f, 0x7f, 0x77,
0x65, 0x87, 0x6c, 0x99, 0x09, 0xfa, 0x87, 0xcf, 0x97, 0x79, 0x8a, 0x75, 0x9e, 0x91, 0x5f, 0x34,
0x58, 0x89, 0x29, 0x04, 0x29, 0x4d, 0x4c, 0x39, 0x4e, 0x8f, 0xf4, 0xf2, 0x65, 0x5c, 0x90, 0xf5,
0xb6, 0x64, 0x2d, 0x93, 0x5b, 0x49, 0xac, 0xa1, 0x3c, 0x8d, 0x20, 0xff, 0xaa, 0xc1, 0xea, 0xf0,
0xf3, 0x4f, 0xde, 0x9c, 0x88, 0x90, 0xa0, 0x3d, 0xfa, 0x5b, 0x97, 0xf4, 0x42, 0xf6, 0x0f, 0x24,
0xfb, 0x1d, 0x72, 0x3b, 0x89, 0xbd, 0x17, 0x7a, 0x0e, 0xf0, 0xa3, 0x1a, 0x77, 0x46, 0x7e, 0xd0,
0x60, 0x1e, 0x9f, 0xfe, 0x94, 0x81, 0x88, 0x6b, 0x4b, 0xca, 0x40, 0x0c, 0xa9, 0x09, 0x2d, 0x4b,
0xd0, 0x5d, 0xb2, 0x9d, 0x04, 0x8a, 0xe2, 0xe2, 0x47, 0xda, 0xfb, 0x93, 0x06, 0xf3, 0x28, 0x0b,
0x29, 0x68, 0x71, 0x25, 0x4a, 0x41, 0x1b, 0x52, 0x1a, 0xfa, 0x8e, 0x44, 0x2b, 0x11, 0x33, 0x09,
0xcd, 0x57, 0x0e, 0x03, 0x32, 0xf3, 0xf4, 0xc8, 0x3e, 0x39, 0x23, 0x5f, 0x6b, 0x90, 0x15, 0x82,
0x42, 0x8a, 0x29, 0x53, 0xd7, 0xd7, 0x2a, 0x7d, 0x6b, 0x0a, 0x4b, 0xc4, 0x32, 0x25, 0xd6, 0x16,
0x29, 0x24, 0x8f, 0x65, 0x3d, 0xd6, 0xae, 0x6f, 0x35, 0x98, 0x53, 0x12, 0x44, 0xb6, 0x27, 0xa6,
0x89, 0x69, 0x9b, 0xbe, 0x33, 0x95, 0x2d, 0x42, 0x19, 0x12, 0xaa, 0x48, 0x36, 0x93, 0xa0, 0x50,
0x26, 0xcc, 0x53, 0x21, 0x52, 0xf2, 0x0a, 0x17, 0xfb, 0x72, 0x42, 0x6e, 0x4e, 0x1e, 0x99, 0x21,
0xd9, 0xd3, 0x8d, 0x69, 0xcd, 0xa7, 0x7d, 0x74, 0x6a, 0xc2, 0x25, 0xc6, 0xf7, 0xa3, 0x06, 0x30,
0x50, 0x0a, 0x32, 0x45, 0xc6, 0xa8, 0xd8, 0xe8, 0xe6, 0xd4, 0xf6, 0x88, 0xb8, 0x23, 0x11, 0x6f,
0x90, 0xd7, 0x27, 0x23, 0x4a, 0x65, 0x22, 0x5f, 0x6a, 0x30, 0xa7, 0x74, 0x24, 0xe5, 0x42, 0x63,
0xd2, 0x95, 0x72, 0xa1, 0x71, 0x41, 0xa3, 0x9b, 0x12, 0x68, 0x83, 0xe4, 0x93, 0x80, 0x94, 0x74,
0xc9, 0x46, 0x0d, 0xc4, 0x26, 0xa5, 0x51, 0x23, 0xfa, 0x96, 0xd2, 0xa8, 0x51, 0x15, 0x4b, 0x6f,
0x94, 0x2f, 0x7d, 0xaa, 0x16, 0x73, 0xdd, 0xfd, 0xbd, 0xa7, 0xe7, 0x79, 0xed, 0xd9, 0x79, 0x5e,
0xfb, 0xeb, 0x3c, 0xaf, 0x7d, 0x73, 0x91, 0xcf, 0x3c, 0xbb, 0xc8, 0x67, 0x7e, 0xbf, 0xc8, 0x67,
0x3e, 0x2d, 0x38, 0xcd, 0xa0, 0xd1, 0xad, 0x19, 0x16, 0x6f, 0xe1, 0x33, 0x1e, 0x89, 0x77, 0x2c,
0x23, 0x06, 0x27, 0x6d, 0xdb, 0xaf, 0xcd, 0xc9, 0x3f, 0x63, 0x6f, 0xfc, 0x1b, 0x00, 0x00, 0xff,
0xff, 0xcd, 0x03, 0x04, 0x72, 0x4c, 0x0e, 0x00, 0x00,
// 1117 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x97, 0x4d, 0x6f, 0x1b, 0x45,
0x18, 0xc7, 0xbd, 0x8d, 0x13, 0x27, 0x4f, 0x12, 0x08, 0x83, 0x29, 0x61, 0x5b, 0x9c, 0xb0, 0xa8,
0xb1, 0xf3, 0xd2, 0x9d, 0xda, 0xbc, 0x95, 0x0a, 0x09, 0xe2, 0x4a, 0xa1, 0x52, 0x2b, 0x54, 0x9c,
0x8a, 0x03, 0x17, 0x6b, 0xbc, 0x5e, 0xad, 0xad, 0xac, 0x77, 0xdc, 0x9d, 0xb5, 0x95, 0x28, 0xca,
0x85, 0x03, 0x02, 0xc1, 0x01, 0xc4, 0x01, 0x84, 0x84, 0xd4, 0x2b, 0x37, 0xbe, 0x02, 0xb7, 0x1e,
0x2b, 0x71, 0xe1, 0x80, 0x10, 0x4a, 0x38, 0xf0, 0x31, 0xd0, 0xbc, 0xac, 0xbd, 0x6b, 0x7b, 0xbd,
0x0e, 0xe2, 0x36, 0x33, 0xfb, 0xbc, 0xfc, 0x9e, 0x67, 0x1e, 0xcf, 0x5f, 0x06, 0xc3, 0x0e, 0x5a,
0xb6, 0xdf, 0x69, 0x7b, 0x01, 0xb6, 0xfb, 0x1d, 0xdc, 0x2f, 0x13, 0xb7, 0xdb, 0x22, 0x65, 0xfc,
0xb8, 0x67, 0xfb, 0x27, 0x66, 0xd7, 0xa7, 0x01, 0x45, 0x57, 0x07, 0x36, 0xa6, 0xdd, 0xef, 0x98,
0xa1, 0x8d, 0x9e, 0x77, 0xa8, 0x43, 0x85, 0x09, 0xe6, 0x2b, 0x69, 0xad, 0xef, 0x58, 0x94, 0x75,
0x28, 0xc3, 0x0d, 0xc2, 0x6c, 0x19, 0x06, 0xf7, 0xcb, 0x0d, 0x3b, 0x20, 0x65, 0xdc, 0x25, 0x4e,
0xdb, 0x23, 0x41, 0x9b, 0x7a, 0xca, 0xf6, 0xba, 0x43, 0xa9, 0xe3, 0xda, 0x98, 0x74, 0xdb, 0x98,
0x78, 0x1e, 0x0d, 0xc4, 0x47, 0xa6, 0xbe, 0x6e, 0x26, 0xb0, 0x71, 0x08, 0x61, 0x61, 0xbc, 0x0b,
0x2f, 0x7e, 0xcc, 0x33, 0xec, 0x5b, 0x16, 0xed, 0x79, 0x41, 0xcd, 0x7e, 0xdc, 0xb3, 0x59, 0x80,
0xd6, 0x21, 0x47, 0x9a, 0x4d, 0xdf, 0x66, 0x6c, 0x5d, 0xdb, 0xd4, 0x4a, 0x4b, 0xb5, 0x70, 0x7b,
0x67, 0xf1, 0x8b, 0x27, 0x1b, 0x99, 0x7f, 0x9e, 0x6c, 0x64, 0x0c, 0x0b, 0xf2, 0x71, 0x57, 0xd6,
0xa5, 0x1e, 0xb3, 0xb9, 0x6f, 0x83, 0xb8, 0xc4, 0xb3, 0xec, 0xd0, 0x57, 0x6d, 0xd1, 0x35, 0x58,
0xb2, 0x68, 0xd3, 0xae, 0xb7, 0x08, 0x6b, 0xad, 0x5f, 0x11, 0xdf, 0x16, 0xf9, 0xc1, 0x3d, 0xc2,
0x5a, 0x28, 0x0f, 0xf3, 0x1e, 0xe5, 0x4e, 0x73, 0x9b, 0x5a, 0x29, 0x5b, 0x93, 0x1b, 0xe3, 0x7d,
0x78, 0x45, 0x24, 0xb9, 0x2b, 0x5a, 0xf2, 0x1f, 0x28, 0x3f, 0xd7, 0x40, 0x9f, 0x14, 0x41, 0xc1,
0xde, 0x80, 0xe7, 0x64, 0xb7, 0xeb, 0xf1, 0x48, 0xab, 0xf2, 0x74, 0x5f, 0x1e, 0x22, 0x1d, 0x16,
0x19, 0x4f, 0xca, 0xf9, 0xae, 0x08, 0xbe, 0xc1, 0x9e, 0x87, 0x20, 0x32, 0x6a, 0xdd, 0xeb, 0x75,
0x1a, 0xb6, 0xaf, 0x2a, 0x58, 0x55, 0xa7, 0x1f, 0x89, 0x43, 0xe3, 0x3e, 0x5c, 0x17, 0x1c, 0x9f,
0x10, 0xb7, 0xdd, 0x24, 0x01, 0xf5, 0x47, 0x8a, 0x79, 0x0d, 0x56, 0x2c, 0xea, 0x8d, 0x72, 0x2c,
0xf3, 0xb3, 0xfd, 0xb1, 0xaa, 0xbe, 0xd2, 0xe0, 0xd5, 0x84, 0x68, 0xaa, 0xb0, 0x22, 0x3c, 0x1f,
0x52, 0xc5, 0x23, 0x86, 0xb0, 0xff, 0x63, 0x69, 0xe1, 0x10, 0x55, 0xe5, 0x3d, 0x5f, 0xe6, 0x7a,
0x6e, 0xa9, 0x21, 0x1a, 0xb8, 0xa6, 0x0d, 0x91, 0x71, 0x5f, 0x25, 0x3b, 0x0c, 0xa8, 0x4f, 0x9c,
0xf4, 0x64, 0x68, 0x0d, 0xe6, 0x8e, 0xec, 0x13, 0x35, 0x6f, 0x7c, 0x19, 0x49, 0xbf, 0xa7, 0xd2,
0x0f, 0x82, 0xa9, 0xf4, 0x79, 0x98, 0xef, 0x13, 0xb7, 0x17, 0x26, 0x97, 0x1b, 0xe3, 0x6d, 0x58,
0x53, 0xa3, 0xd4, 0xbc, 0x54, 0x91, 0x45, 0x78, 0x21, 0xe2, 0xa7, 0x52, 0x20, 0xc8, 0xf2, 0xd9,
0x17, 0x5e, 0x2b, 0x35, 0xb1, 0x36, 0x2a, 0x80, 0x84, 0xe1, 0xa3, 0xe3, 0x07, 0xd4, 0x61, 0x61,
0x0a, 0x04, 0x59, 0xf1, 0x8b, 0x91, 0xf1, 0xc5, 0x3a, 0x12, 0xfc, 0x40, 0xf5, 0x23, 0xf4, 0x51,
0xe1, 0x31, 0x64, 0x5d, 0xea, 0x70, 0xa8, 0xb9, 0xd2, 0x72, 0xe5, 0x9a, 0x39, 0xf9, 0x05, 0x32,
0x1f, 0x50, 0xa7, 0x26, 0x0c, 0x8d, 0x33, 0x78, 0x49, 0xde, 0x84, 0x4b, 0xad, 0xa3, 0x94, 0xf4,
0xe8, 0x00, 0x60, 0xf8, 0x14, 0x89, 0xd6, 0x2e, 0x57, 0xb6, 0x4c, 0xf9, 0x9b, 0x31, 0xf9, 0xbb,
0x65, 0xca, 0xe7, 0x4f, 0xbd, 0x5b, 0xe6, 0xc3, 0xe1, 0x4d, 0xd5, 0x22, 0x9e, 0x91, 0x32, 0x7e,
0xd6, 0xe0, 0xea, 0x68, 0x7e, 0x55, 0xca, 0x01, 0xe4, 0x82, 0xe3, 0x7a, 0xa4, 0x9a, 0x62, 0x52,
0x35, 0x8f, 0x7c, 0xe2, 0x31, 0x62, 0xf1, 0xd0, 0x3c, 0x42, 0x35, 0xfb, 0xf4, 0xcf, 0x8d, 0x4c,
0x6d, 0x21, 0x10, 0xad, 0x41, 0x1f, 0x4e, 0x80, 0x2e, 0xa6, 0x42, 0x4b, 0x88, 0x28, 0xb5, 0xb1,
0x1e, 0x45, 0xad, 0xba, 0x94, 0x76, 0x54, 0x6d, 0x06, 0x86, 0x97, 0xc7, 0xbe, 0x0c, 0x47, 0xaa,
0xc1, 0x0f, 0xd4, 0x85, 0xcb, 0x8d, 0x91, 0x57, 0x37, 0xfe, 0x90, 0xf8, 0xa4, 0x13, 0xb6, 0xdc,
0x38, 0x54, 0x77, 0x1a, 0x9e, 0xaa, 0x10, 0xef, 0xc1, 0x42, 0x57, 0x9c, 0x88, 0x18, 0xcb, 0x95,
0x42, 0x52, 0x1f, 0xa4, 0x5f, 0x58, 0xbe, 0xf4, 0x31, 0xee, 0x29, 0xea, 0x43, 0xae, 0x11, 0xd6,
0x5d, 0xe2, 0xba, 0xe9, 0xbf, 0x9d, 0x3c, 0xcc, 0xb7, 0xbd, 0x6e, 0x2f, 0x10, 0xdd, 0x5a, 0xa9,
0xc9, 0x8d, 0x71, 0x53, 0x55, 0x19, 0x8d, 0x34, 0x9c, 0xea, 0x26, 0x09, 0x48, 0x38, 0xd5, 0x7c,
0x5d, 0xf9, 0x63, 0x15, 0xe6, 0x85, 0x3d, 0xfa, 0x5e, 0x83, 0x9c, 0x7a, 0xa8, 0xd0, 0x6e, 0x12,
0xfc, 0x04, 0x3d, 0xd2, 0xf7, 0x66, 0x33, 0x96, 0x10, 0x46, 0xf9, 0xb3, 0xdf, 0xfe, 0xfe, 0xee,
0xca, 0x2e, 0xda, 0xc6, 0x09, 0xfa, 0xa7, 0x9e, 0x2f, 0x7c, 0xaa, 0xea, 0x3c, 0x43, 0xbf, 0x68,
0xb0, 0x1a, 0x53, 0x08, 0x54, 0x9e, 0x9a, 0x72, 0x92, 0x1e, 0xe9, 0x95, 0xcb, 0xb8, 0x28, 0xd6,
0xdb, 0x82, 0xb5, 0x82, 0x6e, 0x25, 0xb1, 0x86, 0xf2, 0x34, 0x86, 0xfc, 0xab, 0x06, 0x6b, 0xa3,
0xcf, 0x3f, 0x7a, 0x73, 0x2a, 0x42, 0x82, 0xf6, 0xe8, 0x6f, 0x5d, 0xd2, 0x4b, 0xb1, 0x7f, 0x20,
0xd8, 0xef, 0xa0, 0xdb, 0x49, 0xec, 0xfd, 0xd0, 0x73, 0x88, 0x1f, 0xd5, 0xb8, 0x33, 0xf4, 0x83,
0x06, 0x39, 0xf5, 0xf4, 0xa7, 0x0c, 0x44, 0x5c, 0x5b, 0x52, 0x06, 0x62, 0x44, 0x4d, 0x8c, 0x8a,
0x00, 0xdd, 0x43, 0x3b, 0x49, 0xa0, 0x4a, 0x5c, 0x58, 0xa4, 0xbd, 0x3f, 0x69, 0x90, 0x53, 0xb2,
0x90, 0x82, 0x16, 0x57, 0xa2, 0x14, 0xb4, 0x11, 0xa5, 0x31, 0xde, 0x11, 0x68, 0x65, 0x84, 0x93,
0xd0, 0x98, 0x74, 0x18, 0x92, 0xe1, 0xd3, 0x23, 0xfb, 0xe4, 0x0c, 0x7d, 0xad, 0x41, 0x96, 0x0b,
0x0a, 0x2a, 0xa5, 0x4c, 0xdd, 0x40, 0xab, 0xf4, 0xed, 0x19, 0x2c, 0x15, 0x16, 0x16, 0x58, 0xdb,
0xa8, 0x98, 0x3c, 0x96, 0xcd, 0x58, 0xbb, 0xbe, 0xd5, 0x60, 0x41, 0x4a, 0x10, 0xda, 0x99, 0x9a,
0x26, 0xa6, 0x6d, 0xfa, 0xee, 0x4c, 0xb6, 0x0a, 0xca, 0x14, 0x50, 0x25, 0xb4, 0x95, 0x04, 0xa5,
0x64, 0x02, 0x9f, 0x72, 0x91, 0x12, 0x57, 0xb8, 0x34, 0x90, 0x13, 0x74, 0x73, 0xfa, 0xc8, 0x8c,
0xc8, 0x9e, 0x6e, 0xce, 0x6a, 0x3e, 0xeb, 0xa3, 0xd3, 0xe0, 0x2e, 0x31, 0xbe, 0x1f, 0x35, 0x80,
0xa1, 0x52, 0xa0, 0x19, 0x32, 0x46, 0xc5, 0x46, 0xc7, 0x33, 0xdb, 0x2b, 0xc4, 0x5d, 0x81, 0x78,
0x03, 0xbd, 0x3e, 0x1d, 0x51, 0x28, 0x13, 0xfa, 0x52, 0x83, 0x05, 0xa9, 0x23, 0x29, 0x17, 0x1a,
0x93, 0xae, 0x94, 0x0b, 0x8d, 0x0b, 0x9a, 0xb1, 0x25, 0x80, 0x36, 0x51, 0x21, 0x09, 0x48, 0x4a,
0x97, 0x68, 0xd4, 0x50, 0x6c, 0x52, 0x1a, 0x35, 0xa6, 0x6f, 0x29, 0x8d, 0x1a, 0x57, 0xb1, 0xf4,
0x46, 0x31, 0xe1, 0x53, 0xb7, 0x88, 0xeb, 0x56, 0xab, 0x4f, 0xcf, 0x0b, 0xda, 0xb3, 0xf3, 0x82,
0xf6, 0xd7, 0x79, 0x41, 0xfb, 0xe6, 0xa2, 0x90, 0x79, 0x76, 0x51, 0xc8, 0xfc, 0x7e, 0x51, 0xc8,
0x7c, 0x5a, 0x72, 0xda, 0x41, 0xab, 0xd7, 0x30, 0x2d, 0xda, 0xc1, 0x41, 0x8b, 0xf8, 0xac, 0xcd,
0x22, 0x01, 0x8f, 0x45, 0xc8, 0xe0, 0xa4, 0x6b, 0xb3, 0xc6, 0x82, 0xf8, 0x37, 0xf6, 0xc6, 0xbf,
0x01, 0x00, 0x00, 0xff, 0xff, 0x4e, 0x4f, 0xb9, 0xc4, 0x4d, 0x0e, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.

View File

@ -205,33 +205,32 @@ func init() {
func init() { proto.RegisterFile("ethermint/evm/v1alpha1/tx.proto", fileDescriptor_6a305e80b084ab0e) }
var fileDescriptor_6a305e80b084ab0e = []byte{
// 404 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x92, 0x31, 0x6b, 0xdb, 0x40,
0x1c, 0xc5, 0x75, 0x96, 0xda, 0xba, 0xe7, 0x16, 0xca, 0xd1, 0x1a, 0x55, 0x85, 0x93, 0x10, 0x94,
0x6a, 0xb1, 0x84, 0xe5, 0xcd, 0x5b, 0x4d, 0xbd, 0xd5, 0x14, 0x0e, 0x43, 0xa1, 0x9b, 0x64, 0x5f,
0x25, 0x81, 0xa5, 0x13, 0xba, 0xb3, 0x50, 0xf2, 0x09, 0x32, 0x7a, 0xcd, 0x96, 0x8f, 0x93, 0xd1,
0x63, 0x26, 0x13, 0xec, 0x2d, 0x63, 0x3e, 0x41, 0xd0, 0x39, 0xb6, 0xe3, 0x10, 0x43, 0xb6, 0xbf,
0xf4, 0xff, 0xdd, 0xbd, 0xf7, 0x8e, 0x07, 0x4d, 0x2a, 0x62, 0x5a, 0xa4, 0x49, 0x26, 0x3c, 0x5a,
0xa6, 0x5e, 0xd9, 0x0d, 0x66, 0x79, 0x1c, 0x74, 0x3d, 0x51, 0xb9, 0x79, 0xc1, 0x04, 0x43, 0xed,
0x3d, 0xe0, 0xd2, 0x32, 0x75, 0x77, 0x80, 0xf1, 0x39, 0x62, 0x11, 0x93, 0x88, 0x57, 0x4f, 0x5b,
0xda, 0xb0, 0x4e, 0x5c, 0x57, 0x1f, 0x95, 0x84, 0x7d, 0x09, 0xe0, 0xc7, 0x11, 0x8f, 0x86, 0x35,
0x47, 0xe7, 0xe9, 0xb8, 0x42, 0x3e, 0xd4, 0xa6, 0x81, 0x08, 0x74, 0x60, 0x01, 0xa7, 0xe5, 0x63,
0xf7, 0x65, 0x41, 0x77, 0x5c, 0xfd, 0x0a, 0x44, 0x40, 0x24, 0x8b, 0xbe, 0x42, 0x8d, 0x27, 0xe7,
0x54, 0x6f, 0x58, 0xc0, 0x01, 0x83, 0x37, 0x77, 0x2b, 0x13, 0x74, 0x88, 0xfc, 0x85, 0x4c, 0xa8,
0xc5, 0x01, 0x8f, 0x75, 0xd5, 0x02, 0xce, 0xfb, 0x41, 0xeb, 0x7e, 0x65, 0xbe, 0x2b, 0x66, 0x79,
0xdf, 0xee, 0xd8, 0x44, 0x2e, 0x10, 0x82, 0xda, 0xff, 0x82, 0xa5, 0xba, 0x56, 0x03, 0x44, 0xce,
0x7d, 0xed, 0xe2, 0xca, 0x54, 0x6c, 0x1b, 0x1a, 0xc3, 0x4a, 0xd0, 0x8c, 0x27, 0x2c, 0xfb, 0x93,
0x8b, 0x84, 0x65, 0xfc, 0xe0, 0xf3, 0x91, 0xc1, 0xb0, 0xfd, 0x9c, 0xf9, 0x4b, 0xc3, 0xde, 0x7e,
0xbf, 0x00, 0xf0, 0xcb, 0x51, 0x3e, 0x42, 0x79, 0xce, 0x32, 0x4e, 0x6b, 0x5d, 0x69, 0x0c, 0x6c,
0x75, 0xa5, 0x17, 0x0f, 0x6a, 0x33, 0x16, 0x71, 0xbd, 0x61, 0xa9, 0x4e, 0xcb, 0xff, 0x76, 0x2a,
0xfb, 0x6f, 0x16, 0x11, 0x09, 0xa2, 0x4f, 0x50, 0x2d, 0xa8, 0x90, 0xe1, 0x3e, 0x90, 0x7a, 0x44,
0x06, 0x6c, 0x16, 0xb4, 0xa4, 0x85, 0xa0, 0x53, 0x19, 0xa9, 0x49, 0xf6, 0xdf, 0x5b, 0x4b, 0x7e,
0x02, 0xd5, 0x11, 0x8f, 0x50, 0x08, 0xe1, 0x93, 0x57, 0xff, 0x7e, 0x4a, 0xeb, 0xc8, 0xbc, 0xd1,
0x79, 0x15, 0xb6, 0xcb, 0x38, 0xf8, 0x79, 0xbd, 0xc6, 0x60, 0xb9, 0xc6, 0xe0, 0x76, 0x8d, 0xc1,
0x62, 0x83, 0x95, 0xe5, 0x06, 0x2b, 0x37, 0x1b, 0xac, 0xfc, 0xfb, 0x11, 0x25, 0x22, 0x9e, 0x87,
0xee, 0x84, 0xa5, 0xde, 0x84, 0xf1, 0x94, 0x71, 0xef, 0xd0, 0x95, 0x4a, 0xb6, 0x45, 0x9c, 0xe5,
0x94, 0x87, 0x6f, 0x65, 0x4f, 0x7a, 0x0f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x9c, 0x61, 0x2c, 0xf2,
0x9a, 0x02, 0x00, 0x00,
// 400 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x92, 0x41, 0xeb, 0xd3, 0x30,
0x18, 0xc6, 0x9b, 0xb5, 0xea, 0xcc, 0x14, 0x24, 0xe8, 0xa8, 0x15, 0xd2, 0x52, 0x10, 0x7a, 0x59,
0xcb, 0xba, 0xdb, 0x8e, 0xc5, 0xdd, 0x1c, 0x42, 0x18, 0x08, 0xde, 0x52, 0x17, 0xdb, 0xc2, 0xda,
0x94, 0x24, 0x2b, 0xd5, 0x4f, 0xe0, 0x71, 0x57, 0x6f, 0x7e, 0x1c, 0x8f, 0x3b, 0x7a, 0x1a, 0xb2,
0xdd, 0x3c, 0xfa, 0x09, 0xa4, 0x99, 0xdb, 0x9c, 0x38, 0xf8, 0xdf, 0xde, 0xf6, 0xfd, 0x25, 0xcf,
0xf3, 0x84, 0x07, 0xba, 0x4c, 0xe5, 0x4c, 0x94, 0x45, 0xa5, 0x22, 0xd6, 0x94, 0x51, 0x33, 0xa6,
0xab, 0x3a, 0xa7, 0xe3, 0x48, 0xb5, 0x61, 0x2d, 0xb8, 0xe2, 0x68, 0x78, 0x06, 0x42, 0xd6, 0x94,
0xe1, 0x09, 0x70, 0x9e, 0x66, 0x3c, 0xe3, 0x1a, 0x89, 0xba, 0xe9, 0x48, 0x3b, 0xde, 0x8d, 0xeb,
0xba, 0xa3, 0x9a, 0xf0, 0xbf, 0x00, 0xf8, 0x78, 0x2e, 0xb3, 0x59, 0xc7, 0xb1, 0x75, 0xb9, 0x68,
0x51, 0x0c, 0xad, 0x25, 0x55, 0xd4, 0x06, 0x1e, 0x08, 0x06, 0x31, 0x0e, 0xff, 0x2f, 0x18, 0x2e,
0xda, 0x57, 0x54, 0x51, 0xa2, 0x59, 0xf4, 0x1c, 0x5a, 0xb2, 0xf8, 0xc4, 0xec, 0x9e, 0x07, 0x02,
0x90, 0xdc, 0xfb, 0xb9, 0x73, 0xc1, 0x88, 0xe8, 0x5f, 0xc8, 0x85, 0x56, 0x4e, 0x65, 0x6e, 0x9b,
0x1e, 0x08, 0x1e, 0x26, 0x83, 0x5f, 0x3b, 0xf7, 0x81, 0x58, 0xd5, 0x53, 0x7f, 0xe4, 0x13, 0xbd,
0x40, 0x08, 0x5a, 0x1f, 0x04, 0x2f, 0x6d, 0xab, 0x03, 0x88, 0x9e, 0xa7, 0xd6, 0xe7, 0xaf, 0xae,
0xe1, 0xfb, 0xd0, 0x99, 0xb5, 0x8a, 0x55, 0xb2, 0xe0, 0xd5, 0x9b, 0x5a, 0x15, 0xbc, 0x92, 0x17,
0x9f, 0x7f, 0x18, 0x0c, 0x87, 0xff, 0x32, 0x6f, 0x59, 0x3a, 0x39, 0xef, 0x37, 0x00, 0x3e, 0xbb,
0xca, 0x47, 0x98, 0xac, 0x79, 0x25, 0x59, 0xa7, 0xab, 0x8d, 0x81, 0xa3, 0xae, 0xf6, 0x12, 0x41,
0x6b, 0xc5, 0x33, 0x69, 0xf7, 0x3c, 0x33, 0x18, 0xc4, 0x2f, 0x6e, 0x65, 0x7f, 0xcd, 0x33, 0xa2,
0x41, 0xf4, 0x04, 0x9a, 0x82, 0x29, 0x1d, 0xee, 0x11, 0xe9, 0x46, 0xe4, 0xc0, 0xbe, 0x60, 0x0d,
0x13, 0x8a, 0x2d, 0x75, 0xa4, 0x3e, 0x39, 0x7f, 0x1f, 0x2d, 0xc5, 0x05, 0x34, 0xe7, 0x32, 0x43,
0x29, 0x84, 0x7f, 0xbd, 0xfa, 0xcb, 0x5b, 0x5a, 0x57, 0xe6, 0x9d, 0xd1, 0x9d, 0xb0, 0x53, 0xc6,
0x24, 0xf9, 0xb6, 0xc7, 0x60, 0xbb, 0xc7, 0xe0, 0xc7, 0x1e, 0x83, 0xcd, 0x01, 0x1b, 0xdb, 0x03,
0x36, 0xbe, 0x1f, 0xb0, 0xf1, 0x2e, 0xc8, 0x0a, 0x95, 0xaf, 0xd3, 0xf0, 0x3d, 0x2f, 0x23, 0x95,
0x53, 0x21, 0x0b, 0x19, 0x5d, 0xca, 0xd2, 0xea, 0xba, 0xa8, 0x8f, 0x35, 0x93, 0xe9, 0x7d, 0x5d,
0x94, 0xc9, 0xef, 0x00, 0x00, 0x00, 0xff, 0xff, 0x4e, 0x06, 0x55, 0xd8, 0x9b, 0x02, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.