diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b55bfbdccb5fdbdbe4bf557dae49a891682faca4..b1badac12ec11df37d5d3d813d93994e599b6d71 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,9 +6,9 @@ jobs: steps: - uses: actions/checkout@v2 - name: Install Go - uses: actions/setup-go@v2.1.3 + uses: actions/setup-go@v2 with: - go-version: 1.16.7 + go-version: 1.17 - name: "Build binaries" run: make all - name: "Run tests" diff --git a/.github/workflows/dockerimage-latest.yml b/.github/workflows/dockerimage-latest.yml deleted file mode 100644 index 0bfa73503e9ad6448910b24705e4225dfe6f0d8a..0000000000000000000000000000000000000000 --- a/.github/workflows/dockerimage-latest.yml +++ /dev/null @@ -1,26 +0,0 @@ -name: Docker Images For Latest Branches - -on: - push: - branches: - - master - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Build docker image - env: - DOCKERHUB: ${{ secrets.DOCKERHUB }} - DOCKERHUB_KEY: ${{ secrets.DOCKERHUB_KEY }} - run: | - set -x - ls -l - echo "Docker login" - docker login -u $DOCKERHUB -p $DOCKERHUB_KEY - echo "Running build" - docker build -t maticnetwork/bor:${GITHUB_REF/refs\/heads\//} . - echo "Pushing image" - docker push maticnetwork/bor:${GITHUB_REF/refs\/heads\//} - echo "Done" diff --git a/.github/workflows/dockerimage.yml b/.github/workflows/dockerimage.yml deleted file mode 100644 index a357399dfbb824ef96304ccf693d677750ce2c54..0000000000000000000000000000000000000000 --- a/.github/workflows/dockerimage.yml +++ /dev/null @@ -1,25 +0,0 @@ -name: Bor Docker Image CI - -on: - push: - tags: - - 'v*.*.*' - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Build the Bor Docker image - env: - DOCKERHUB: ${{ secrets.DOCKERHUB }} - DOCKERHUB_KEY: ${{ secrets.DOCKERHUB_KEY }} - run: | - ls -l - echo "Docker login" - docker login -u $DOCKERHUB -p $DOCKERHUB_KEY - echo "running build" - docker build -t maticnetwork/bor:${GITHUB_REF/refs\/tags\//} . - echo "pushing image" - docker push maticnetwork/bor:${GITHUB_REF/refs\/tags\//} - echo "DONE!" diff --git a/.github/workflows/linuxpackage.yml b/.github/workflows/linuxpackage.yml deleted file mode 100644 index f4937e426fb9d01ba3de2086535adf66ad314343..0000000000000000000000000000000000000000 --- a/.github/workflows/linuxpackage.yml +++ /dev/null @@ -1,67 +0,0 @@ -name: Linux package - -on: - push: - tags: - - "v*.*.*" -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - - name: Install Go - uses: actions/setup-go@v1 - with: - go-version: 1.17 - - - name: Set up Ruby 2.6 - uses: actions/setup-ruby@v1 - with: - ruby-version: 2.6 - - - name: Retrieve release version - run: | - echo "RELEASE_VERSION=${GITHUB_REF/refs\/tags\/v/}" >> $GITHUB_ENV - - - name: Build package - run: | - set -x - - echo "Release version: ${{ env.RELEASE_VERSION }}" - - sudo apt-get -yqq install libpq-dev build-essential - gem install --no-document fpm - fpm --version - - make bor-all - - fpm -s dir -t deb --deb-user root --deb-group root -n matic-bor -v ${{ env.RELEASE_VERSION }} \ - build/bin/bor=/usr/bin/ \ - build/bin/bootnode=/usr/bin/ - - mkdir packages-v${{ env.RELEASE_VERSION }} - - mv matic-bor_${{ env.RELEASE_VERSION }}_amd64.deb packages-v${{ env.RELEASE_VERSION }}/ - - ls packages-v${{ env.RELEASE_VERSION }}/ - - - name: S3 upload - uses: jakejarvis/s3-sync-action@master - with: - args: --acl public-read - env: - AWS_S3_BUCKET: ${{ secrets.AWS_S3_BUCKET }} - AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - AWS_REGION: "us-east-1" # optional: defaults to us-east-1 - SOURCE_DIR: "packages-v${{ env.RELEASE_VERSION }}" - DEST_DIR: "v${{ env.RELEASE_VERSION }}" - - - name: Slack Notification - uses: rtCamp/action-slack-notify@v2.0.0 - env: - SLACK_CHANNEL: code-releases - SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} - SLACK_TITLE: "New linux package for Bor v${{ env.RELEASE_VERSION }} just got released" - SLACK_MESSAGE: "Package has been uploaded to S3 bucket for public use and available at https://matic-public.s3.amazonaws.com/v${{ env.RELEASE_VERSION }}/matic-bor_${{ env.RELEASE_VERSION }}_amd64.deb" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000000000000000000000000000000000000..b615cf639edbcdc48aa4ed70f2fa6716331f1c39 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,43 @@ +name: Release + +on: + push: + branches-ignore: + - '**' + tags: + - 'v*.*.*' + # to be used by fork patch-releases ^^ + - 'v*.*.*-*' + +jobs: + goreleaser: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + with: + fetch-depth: 0 + + - name: Set up Go + uses: actions/setup-go@master + with: + go-version: 1.17.x + + - name: Prepare + id: prepare + run: | + TAG=${GITHUB_REF#refs/tags/} + echo ::set-output name=tag_name::${TAG} + + - name: Set up QEMU + uses: docker/setup-qemu-action@v1 + + - name: Run GoReleaser + run: | + make release + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + VERSION: ${{ steps.prepare.outputs.tag_name }} + SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} + DOCKER_USERNAME: ${{ secrets.DOCKERHUB }} + DOCKER_PASSWORD: ${{ secrets.DOCKERHUB_KEY }} diff --git a/.gitignore b/.gitignore index 1ee8b83022efe585f890e9104913de9cf40bfacf..ad4242c5195cd1a9e3732e8c3d2e2639f2da5d1b 100644 --- a/.gitignore +++ b/.gitignore @@ -47,3 +47,7 @@ profile.cov /dashboard/assets/package-lock.json **/yarn-error.log +./test +./bor-debug-* + +dist diff --git a/.goreleaser.yml b/.goreleaser.yml new file mode 100644 index 0000000000000000000000000000000000000000..b25a3164498889cf1792c2ea12d07f69a30adf57 --- /dev/null +++ b/.goreleaser.yml @@ -0,0 +1,126 @@ +project_name: bor + +release: + disable: false + draft: true + prerelease: auto + +builds: + - id: darwin-amd64 + main: ./cmd/geth + binary: bor + goos: + - darwin + goarch: + - amd64 + env: + - CC=o64-clang + - CXX=o64-clang++ + ldflags: + -s -w + + - id: darwin-arm64 + main: ./cmd/geth + binary: bor + goos: + - darwin + goarch: + - arm64 + env: + - CC=oa64-clang + - CXX=oa64-clang++ + ldflags: + -s -w + + - id: linux-amd64 + main: ./cmd/geth + binary: bor + goos: + - linux + goarch: + - amd64 + env: + - CC=gcc + - CXX=g++ + ldflags: + # We need to build a static binary because we are building in a glibc based system and running in a musl container + -s -w -linkmode external -extldflags "-static" + + - id: linux-arm64 + main: ./cmd/geth + binary: bor + goos: + - linux + goarch: + - arm64 + env: + - CC=aarch64-linux-gnu-gcc + - CXX=aarch64-linux-gnu-g++ + ldflags: + # We need to build a static binary because we are building in a glibc based system and running in a musl container + -s -w -linkmode external -extldflags "-static" + +nfpms: + - vendor: 0xPolygon + homepage: https://polygon.technology + maintainer: Polygon Team <team@polygon.technology> + description: Polygon Blockchain + license: GPLv3 LGPLv3 + + formats: + - apk + - deb + - rpm + + contents: + - src: builder/files/bor.service + dst: /lib/systemd/system/bor.service + type: config + + overrides: + rpm: + replacements: + amd64: x86_64 + +snapshot: + name_template: "{{ .Tag }}.next" + +dockers: + - image_templates: + - 0xpolygon/{{ .ProjectName }}:{{ .Version }}-amd64 + dockerfile: Dockerfile.release + use: buildx + goarch: amd64 + ids: + - linux-amd64 + build_flag_templates: + - --platform=linux/amd64 + skip_push: true + + - image_templates: + - 0xpolygon/{{ .ProjectName }}:{{ .Version }}-arm64 + dockerfile: Dockerfile.release + use: buildx + goarch: arm64 + ids: + - linux-arm64 + build_flag_templates: + - --platform=linux/arm64 + skip_push: true + +docker_manifests: + - name_template: 0xpolygon/{{ .ProjectName }}:{{ .Version }} + image_templates: + - 0xpolygon/{{ .ProjectName }}:{{ .Version }}-amd64 + - 0xpolygon/{{ .ProjectName }}:{{ .Version }}-arm64 + + - name_template: 0xpolygon/{{ .ProjectName }}:latest + image_templates: + - 0xpolygon/{{ .ProjectName }}:{{ .Version }}-amd64 + - 0xpolygon/{{ .ProjectName }}:{{ .Version }}-arm64 + +announce: + slack: + enabled: true + # The name of the channel that the user selected as a destination for webhook messages. + channel: '#code-releases' diff --git a/Dockerfile b/Dockerfile index c03cfacad80655d22c6a5e54f6c1a524a47fb3e0..8af791ab3f84b71acc407559adc10cdc4b7d3723 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,18 +1,17 @@ -# Build Geth in a stock Go builder container -FROM golang:1.17-alpine as builder +FROM golang:latest -RUN apk add --no-cache make gcc musl-dev linux-headers git bash +ARG BOR_DIR=/bor +ENV BOR_DIR=$BOR_DIR -ADD . /bor -RUN cd /bor && make bor-all +RUN apt-get update -y && apt-get upgrade -y \ + && apt install build-essential git -y \ + && mkdir -p /bor -CMD ["/bin/bash"] +WORKDIR ${BOR_DIR} +COPY . . +RUN make bor-all -# Pull Bor into a second stage deploy alpine container -FROM alpine:latest +ENV SHELL /bin/bash +EXPOSE 8545 8546 8547 30303 30303/udp -RUN apk add --no-cache ca-certificates -COPY --from=builder /bor/build/bin/bor /usr/local/bin/ -COPY --from=builder /bor/build/bin/bootnode /usr/local/bin/ - -EXPOSE 8545 8546 8547 30303 30303/udp \ No newline at end of file +ENTRYPOINT ["bor"] diff --git a/Dockerfile.alltools b/Dockerfile.alltools index 10cf1392e7eb00c64adf476fbaba20e6d21a91d5..53be8bc95043ac5e4768d81b86b7d83a65188a73 100644 --- a/Dockerfile.alltools +++ b/Dockerfile.alltools @@ -9,7 +9,10 @@ RUN cd /bor && make bor-all # Pull all binaries into a second stage deploy alpine container FROM alpine:latest -RUN apk add --no-cache ca-certificates +RUN set -x \ + && apk add --update --no-cache \ + ca-certificates \ + && rm -rf /var/cache/apk/* COPY --from=builder /bor/build/bin/* /usr/local/bin/ -EXPOSE 8545 8546 30303 30303/udp \ No newline at end of file +EXPOSE 8545 8546 30303 30303/udp diff --git a/Dockerfile.release b/Dockerfile.release new file mode 100644 index 0000000000000000000000000000000000000000..439524edbf62bda6fd65a802020c51e5cd9aa6a6 --- /dev/null +++ b/Dockerfile.release @@ -0,0 +1,7 @@ +FROM alpine:3.14 + +RUN apk add --no-cache ca-certificates +COPY bor /usr/local/bin/ + +EXPOSE 8545 8546 8547 30303 30303/udp +ENTRYPOINT ["bor"] diff --git a/Makefile b/Makefile index 8a9fbaa0a2e84666ce7155691ee41ae7423b0137..462f129f5182959023f577b2f45f685ac86e6285 100644 --- a/Makefile +++ b/Makefile @@ -13,6 +13,9 @@ GO ?= latest GORUN = env GO111MODULE=on go run GOPATH = $(shell go env GOPATH) +protoc: + protoc --go_out=. --go-grpc_out=. ./command/server/proto/*.proto + bor: $(GORUN) build/ci.go install ./cmd/geth mkdir -p $(GOPATH)/bin/ @@ -160,3 +163,37 @@ geth-windows-amd64: $(GORUN) build/ci.go xgo -- --go=$(GO) --targets=windows/amd64 -v ./cmd/geth @echo "Windows amd64 cross compilation done:" @ls -ld $(GOBIN)/geth-windows-* | grep amd64 + +PACKAGE_NAME := github.com/maticnetwork/bor +GOLANG_CROSS_VERSION ?= v1.17.2 + +.PHONY: release-dry-run +release-dry-run: + @docker run \ + --rm \ + --privileged \ + -e CGO_ENABLED=1 \ + -e GITHUB_TOKEN \ + -e DOCKER_USERNAME \ + -e DOCKER_PASSWORD \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v `pwd`:/go/src/$(PACKAGE_NAME) \ + -w /go/src/$(PACKAGE_NAME) \ + ghcr.io/troian/golang-cross:${GOLANG_CROSS_VERSION} \ + --rm-dist --skip-validate --skip-publish + +.PHONY: release +release: + @docker run \ + --rm \ + --privileged \ + -e CGO_ENABLED=1 \ + -e GITHUB_TOKEN \ + -e DOCKER_USERNAME \ + -e DOCKER_PASSWORD \ + -e SLACK_WEBHOOK \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v `pwd`:/go/src/$(PACKAGE_NAME) \ + -w /go/src/$(PACKAGE_NAME) \ + ghcr.io/troian/golang-cross:${GOLANG_CROSS_VERSION} \ + --rm-dist --skip-validate diff --git a/README.md b/README.md index d5bb010c3d2d7c8ac2c72f60ed55e0c23ab034c8..b07c07a40f27dee6e7fa31972708b5b3cb96d53b 100644 --- a/README.md +++ b/README.md @@ -113,6 +113,12 @@ them using your favourite package manager. Once the dependencies are installed, <hr style="margin-top: 3em; margin-bottom: 3em;"> +Build the beta client: + +```shell +go build -o bor-beta command/*.go +``` + ## License The go-ethereum library (i.e. all code outside of the `cmd` directory) is licensed under the diff --git a/builder/files/bor.service b/builder/files/bor.service new file mode 100644 index 0000000000000000000000000000000000000000..18d075f79909cb03187286b6949831f6f67f9ec9 --- /dev/null +++ b/builder/files/bor.service @@ -0,0 +1,18 @@ +[Unit] + Description=bor + StartLimitIntervalSec=500 + StartLimitBurst=5 + +[Service] + Restart=on-failure + RestartSec=5s + WorkingDirectory=$NODE_DIR + EnvironmentFile=/etc/matic/metadata + ExecStart=/usr/local/bin/bor $VALIDATOR_ADDRESS + Type=simple + User=$USER + KillSignal=SIGINT + TimeoutStopSec=120 + +[Install] + WantedBy=multi-user.target diff --git a/command/account.go b/command/account.go new file mode 100644 index 0000000000000000000000000000000000000000..747b6b8dbaea8131965e6e35dad5d8b8ceb248d1 --- /dev/null +++ b/command/account.go @@ -0,0 +1,36 @@ +package main + +import "github.com/mitchellh/cli" + +type Account struct { + UI cli.Ui +} + +// Help implements the cli.Command interface +func (a *Account) Help() string { + return `Usage: bor account <subcommand> + + This command groups actions to interact with accounts. + + List the running deployments: + + $ bor account new + + Display the status of a specific deployment: + + $ bor account import + + List the imported accounts in the keystore: + + $ bor account list` +} + +// Synopsis implements the cli.Command interface +func (a *Account) Synopsis() string { + return "Interact with accounts" +} + +// Run implements the cli.Command interface +func (a *Account) Run(args []string) int { + return cli.RunResultHelp +} diff --git a/command/account_import.go b/command/account_import.go new file mode 100644 index 0000000000000000000000000000000000000000..331a45aac6f852020ece7576eb1a660962144fdf --- /dev/null +++ b/command/account_import.go @@ -0,0 +1,74 @@ +package main + +import ( + "fmt" + + "github.com/ethereum/go-ethereum/cmd/utils" + "github.com/ethereum/go-ethereum/command/flagset" + "github.com/ethereum/go-ethereum/crypto" +) + +type AccountImportCommand struct { + *Meta +} + +// Help implements the cli.Command interface +func (a *AccountImportCommand) Help() string { + return `Usage: bor account import + + Import a private key into a new account. + + Import an account: + + $ bor account import key.json + + ` + a.Flags().Help() +} + +func (a *AccountImportCommand) Flags() *flagset.Flagset { + return a.NewFlagSet("account import") +} + +// Synopsis implements the cli.Command interface +func (a *AccountImportCommand) Synopsis() string { + return "Import a private key into a new account" +} + +// Run implements the cli.Command interface +func (a *AccountImportCommand) Run(args []string) int { + flags := a.Flags() + if err := flags.Parse(args); err != nil { + a.UI.Error(err.Error()) + return 1 + } + + args = flags.Args() + if len(args) != 1 { + a.UI.Error("Expected one argument") + return 1 + } + key, err := crypto.LoadECDSA(args[0]) + if err != nil { + a.UI.Error(fmt.Sprintf("Failed to load the private key '%s': %v", args[0], err)) + return 1 + } + + keystore, err := a.GetKeystore() + if err != nil { + a.UI.Error(fmt.Sprintf("Failed to get keystore: %v", err)) + return 1 + } + + password, err := a.AskPassword() + if err != nil { + a.UI.Error(err.Error()) + return 1 + } + + acct, err := keystore.ImportECDSA(key, password) + if err != nil { + utils.Fatalf("Could not create the account: %v", err) + } + a.UI.Output(fmt.Sprintf("Account created: %s", acct.Address.String())) + return 0 +} diff --git a/command/account_list.go b/command/account_list.go new file mode 100644 index 0000000000000000000000000000000000000000..d41e0c0d654669e5717de421ba3d91332736ed40 --- /dev/null +++ b/command/account_list.go @@ -0,0 +1,62 @@ +package main + +import ( + "fmt" + + "github.com/ethereum/go-ethereum/accounts" + "github.com/ethereum/go-ethereum/command/flagset" +) + +type AccountListCommand struct { + *Meta +} + +// Help implements the cli.Command interface +func (a *AccountListCommand) Help() string { + return `Usage: bor account list + + List the local accounts. + + ` + a.Flags().Help() +} + +func (a *AccountListCommand) Flags() *flagset.Flagset { + return a.NewFlagSet("account list") +} + +// Synopsis implements the cli.Command interface +func (a *AccountListCommand) Synopsis() string { + return "List the local accounts" +} + +// Run implements the cli.Command interface +func (a *AccountListCommand) Run(args []string) int { + flags := a.Flags() + if err := flags.Parse(args); err != nil { + a.UI.Error(err.Error()) + return 1 + } + + keystore, err := a.GetKeystore() + if err != nil { + a.UI.Error(fmt.Sprintf("Failed to get keystore: %v", err)) + return 1 + } + a.UI.Output(formatAccounts(keystore.Accounts())) + return 0 +} + +func formatAccounts(accts []accounts.Account) string { + if len(accts) == 0 { + return "No accounts found" + } + + rows := make([]string, len(accts)+1) + rows[0] = "Index|Address" + for i, d := range accts { + rows[i+1] = fmt.Sprintf("%d|%s", + i, + d.Address.String()) + } + return formatList(rows) +} diff --git a/command/account_new.go b/command/account_new.go new file mode 100644 index 0000000000000000000000000000000000000000..59118a9a3764e70cf2305d2ffb752a9f663b0b60 --- /dev/null +++ b/command/account_new.go @@ -0,0 +1,62 @@ +package main + +import ( + "fmt" + + "github.com/ethereum/go-ethereum/command/flagset" +) + +type AccountNewCommand struct { + *Meta +} + +// Help implements the cli.Command interface +func (a *AccountNewCommand) Help() string { + return `Usage: bor account new + + Create a new local account. + + ` + a.Flags().Help() +} + +func (a *AccountNewCommand) Flags() *flagset.Flagset { + return a.NewFlagSet("account new") +} + +// Synopsis implements the cli.Command interface +func (a *AccountNewCommand) Synopsis() string { + return "Create a new local account" +} + +// Run implements the cli.Command interface +func (a *AccountNewCommand) Run(args []string) int { + flags := a.Flags() + if err := flags.Parse(args); err != nil { + a.UI.Error(err.Error()) + return 1 + } + + keystore, err := a.GetKeystore() + if err != nil { + a.UI.Error(fmt.Sprintf("Failed to get keystore: %v", err)) + return 1 + } + + password, err := a.AskPassword() + if err != nil { + a.UI.Error(err.Error()) + return 1 + } + + account, err := keystore.NewAccount(password) + if err != nil { + a.UI.Error(fmt.Sprintf("Failed to create new account: %v", err)) + return 1 + } + + a.UI.Output("\nYour new key was generated") + a.UI.Output(fmt.Sprintf("Public address of the key: %s", account.Address.Hex())) + a.UI.Output(fmt.Sprintf("Path of the secret key file: %s", account.URL.Path)) + + return 0 +} diff --git a/command/chain.go b/command/chain.go new file mode 100644 index 0000000000000000000000000000000000000000..ed8ca9a5f868b8e74dc20821948c4167e9dbfa4d --- /dev/null +++ b/command/chain.go @@ -0,0 +1,31 @@ +package main + +import ( + "github.com/mitchellh/cli" +) + +// ChainCommand is the command to group the peers commands +type ChainCommand struct { + UI cli.Ui +} + +// Help implements the cli.Command interface +func (c *ChainCommand) Help() string { + return `Usage: bor chain <subcommand> + + This command groups actions to interact with the chain. + + Set the new head of the chain: + + $ bor chain sethead <number>` +} + +// Synopsis implements the cli.Command interface +func (c *ChainCommand) Synopsis() string { + return "Interact with the chain" +} + +// Run implements the cli.Command interface +func (c *ChainCommand) Run(args []string) int { + return cli.RunResultHelp +} diff --git a/command/chain_sethead.go b/command/chain_sethead.go new file mode 100644 index 0000000000000000000000000000000000000000..0dfed6268bedd3c4a3fba7c050c45aaa869e731d --- /dev/null +++ b/command/chain_sethead.go @@ -0,0 +1,91 @@ +package main + +import ( + "context" + "fmt" + "strconv" + + "github.com/ethereum/go-ethereum/command/flagset" + "github.com/ethereum/go-ethereum/command/server/proto" +) + +// ChainSetHeadCommand is the command to group the peers commands +type ChainSetHeadCommand struct { + *Meta2 + + yes bool +} + +// Help implements the cli.Command interface +func (c *ChainSetHeadCommand) Help() string { + return `Usage: bor chain sethead <number> [--yes] + + This command sets the current chain to a certain block` +} + +func (c *ChainSetHeadCommand) Flags() *flagset.Flagset { + flags := c.NewFlagSet("chain sethead") + + flags.BoolFlag(&flagset.BoolFlag{ + Name: "yes", + Usage: "Force set head", + Default: false, + Value: &c.yes, + }) + return flags +} + +// Synopsis implements the cli.Command interface +func (c *ChainSetHeadCommand) Synopsis() string { + return "Set the new head of the chain" +} + +// Run implements the cli.Command interface +func (c *ChainSetHeadCommand) Run(args []string) int { + flags := c.Flags() + if err := flags.Parse(args); err != nil { + c.UI.Error(err.Error()) + return 1 + } + + args = flags.Args() + if len(args) != 1 { + c.UI.Error("No number provided") + return 1 + } + + borClt, err := c.BorConn() + if err != nil { + c.UI.Error(err.Error()) + return 1 + } + + arg := args[0] + fmt.Println(arg) + + number, err := strconv.Atoi(arg) + if err != nil { + c.UI.Error(err.Error()) + return 1 + } + + if !c.yes { + response, err := c.UI.Ask("Are you sure you want to reset the database? (y/n)") + if err != nil { + c.UI.Error(err.Error()) + return 1 + } + if response != "y" { + c.UI.Output("set head aborted") + return 0 + } + } + + if _, err := borClt.ChainSetHead(context.Background(), &proto.ChainSetHeadRequest{Number: uint64(number)}); err != nil { + c.UI.Error(err.Error()) + return 1 + } + + c.UI.Output("Done!") + return 0 +} diff --git a/command/debug.go b/command/debug.go new file mode 100644 index 0000000000000000000000000000000000000000..5ea2c9f44a270cad9b7627398b0de1c97193181d --- /dev/null +++ b/command/debug.go @@ -0,0 +1,242 @@ +package main + +// Based on https://github.com/hashicorp/nomad/blob/main/command/operator_debug.go + +import ( + "archive/tar" + "compress/gzip" + "context" + "encoding/hex" + "fmt" + "io" + "io/ioutil" + "os" + "os/signal" + "path/filepath" + "strings" + "syscall" + "time" + + "github.com/ethereum/go-ethereum/command/flagset" + "github.com/ethereum/go-ethereum/command/server/proto" +) + +type DebugCommand struct { + *Meta2 + + seconds uint64 + output string +} + +// Help implements the cli.Command interface +func (d *DebugCommand) Help() string { + return `Usage: bor debug + + Build an archive containing Bor pprof traces + + ` + d.Flags().Help() +} + +func (d *DebugCommand) Flags() *flagset.Flagset { + flags := d.NewFlagSet("debug") + + flags.Uint64Flag(&flagset.Uint64Flag{ + Name: "seconds", + Usage: "seconds to trace", + Value: &d.seconds, + Default: 2, + }) + flags.StringFlag(&flagset.StringFlag{ + Name: "output", + Value: &d.output, + Usage: "Output directory", + }) + + return flags +} + +// Synopsis implements the cli.Command interface +func (d *DebugCommand) Synopsis() string { + return "Build an archive containing Bor pprof traces" +} + +// Run implements the cli.Command interface +func (d *DebugCommand) Run(args []string) int { + flags := d.Flags() + if err := flags.Parse(args); err != nil { + d.UI.Error(err.Error()) + return 1 + } + + clt, err := d.BorConn() + if err != nil { + d.UI.Error(err.Error()) + return 1 + } + + stamped := "bor-debug-" + time.Now().UTC().Format("2006-01-02-150405Z") + + // Create the output directory + var tmp string + if d.output != "" { + // User specified output directory + tmp = filepath.Join(d.output, stamped) + _, err := os.Stat(tmp) + if !os.IsNotExist(err) { + d.UI.Error("Output directory already exists") + return 1 + } + } else { + // Generate temp directory + tmp, err = ioutil.TempDir(os.TempDir(), stamped) + if err != nil { + d.UI.Error(fmt.Sprintf("Error creating tmp directory: %s", err.Error())) + return 1 + } + defer os.RemoveAll(tmp) + } + + d.UI.Output("Starting debugger...") + d.UI.Output("") + + // ensure destine folder exists + if err := os.MkdirAll(tmp, os.ModePerm); err != nil { + d.UI.Error(fmt.Sprintf("failed to create parent directory: %v", err)) + return 1 + } + + pprofProfile := func(ctx context.Context, profile string, filename string) error { + req := &proto.PprofRequest{ + Seconds: int64(d.seconds), + } + switch profile { + case "cpu": + req.Type = proto.PprofRequest_CPU + case "trace": + req.Type = proto.PprofRequest_TRACE + default: + req.Type = proto.PprofRequest_LOOKUP + req.Profile = profile + } + resp, err := clt.Pprof(ctx, req) + if err != nil { + return err + } + // write file + raw, err := hex.DecodeString(resp.Payload) + if err != nil { + return err + } + if err := ioutil.WriteFile(filepath.Join(tmp, filename+".prof"), raw, 0755); err != nil { + return err + } + return nil + } + + ctx, cancelFn := context.WithCancel(context.Background()) + trapSignal(cancelFn) + + profiles := map[string]string{ + "heap": "heap", + "cpu": "cpu", + "trace": "trace", + } + for profile, filename := range profiles { + if err := pprofProfile(ctx, profile, filename); err != nil { + d.UI.Error(fmt.Sprintf("Error creating profile '%s': %v", profile, err)) + return 1 + } + } + + // Exit before archive if output directory was specified + if d.output != "" { + d.UI.Output(fmt.Sprintf("Created debug directory: %s", tmp)) + return 0 + } + + // Create archive tarball + archiveFile := stamped + ".tar.gz" + if err = tarCZF(archiveFile, tmp, stamped); err != nil { + d.UI.Error(fmt.Sprintf("Error creating archive: %s", err.Error())) + return 1 + } + + d.UI.Output(fmt.Sprintf("Created debug archive: %s", archiveFile)) + return 0 +} + +func trapSignal(cancel func()) { + sigCh := make(chan os.Signal, 1) + signal.Notify(sigCh, + syscall.SIGHUP, + syscall.SIGINT, + syscall.SIGTERM, + syscall.SIGQUIT) + + go func() { + <-sigCh + cancel() + }() +} + +func tarCZF(archive string, src, target string) error { + // ensure the src actually exists before trying to tar it + if _, err := os.Stat(src); err != nil { + return fmt.Errorf("unable to tar files - %v", err.Error()) + } + + // create the archive + fh, err := os.Create(archive) + if err != nil { + return err + } + defer fh.Close() + + zz := gzip.NewWriter(fh) + defer zz.Close() + + tw := tar.NewWriter(zz) + defer tw.Close() + + // tar + return filepath.Walk(src, func(file string, fi os.FileInfo, err error) error { + // return on any error + if err != nil { + return err + } + if !fi.Mode().IsRegular() { + return nil + } + + header, err := tar.FileInfoHeader(fi, fi.Name()) + if err != nil { + return err + } + + // remove leading path to the src, so files are relative to the archive + path := strings.ReplaceAll(file, src, "") + if target != "" { + path = filepath.Join([]string{target, path}...) + } + path = strings.TrimPrefix(path, string(filepath.Separator)) + + header.Name = path + + if err := tw.WriteHeader(header); err != nil { + return err + } + + // copy the file contents + f, err := os.Open(file) + if err != nil { + return err + } + + if _, err := io.Copy(tw, f); err != nil { + return err + } + + f.Close() + return nil + }) +} diff --git a/command/flagset/flagset.go b/command/flagset/flagset.go new file mode 100644 index 0000000000000000000000000000000000000000..4388dd03fc2885517c93747a3949fd06acb745ee --- /dev/null +++ b/command/flagset/flagset.go @@ -0,0 +1,242 @@ +package flagset + +import ( + "flag" + "fmt" + "math/big" + "strings" + "time" +) + +type Flagset struct { + flags []*FlagVar + set *flag.FlagSet +} + +func NewFlagSet(name string) *Flagset { + f := &Flagset{ + flags: []*FlagVar{}, + set: flag.NewFlagSet(name, flag.ContinueOnError), + } + return f +} + +type FlagVar struct { + Name string + Usage string +} + +func (f *Flagset) addFlag(fl *FlagVar) { + f.flags = append(f.flags, fl) +} + +func (f *Flagset) Help() string { + str := "Options:\n\n" + items := []string{} + for _, item := range f.flags { + items = append(items, fmt.Sprintf(" -%s\n %s", item.Name, item.Usage)) + } + return str + strings.Join(items, "\n\n") +} + +func (f *Flagset) Parse(args []string) error { + return f.set.Parse(args) +} + +func (f *Flagset) Args() []string { + return f.set.Args() +} + +type BoolFlag struct { + Name string + Usage string + Default bool + Value *bool +} + +func (f *Flagset) BoolFlag(b *BoolFlag) { + f.addFlag(&FlagVar{ + Name: b.Name, + Usage: b.Usage, + }) + f.set.BoolVar(b.Value, b.Name, b.Default, b.Usage) +} + +type StringFlag struct { + Name string + Usage string + Default string + Value *string +} + +func (f *Flagset) StringFlag(b *StringFlag) { + f.addFlag(&FlagVar{ + Name: b.Name, + Usage: b.Usage, + }) + f.set.StringVar(b.Value, b.Name, b.Default, b.Usage) +} + +type IntFlag struct { + Name string + Usage string + Value *int + Default int +} + +func (f *Flagset) IntFlag(i *IntFlag) { + f.addFlag(&FlagVar{ + Name: i.Name, + Usage: i.Usage, + }) + f.set.IntVar(i.Value, i.Name, i.Default, i.Usage) +} + +type Uint64Flag struct { + Name string + Usage string + Value *uint64 + Default uint64 +} + +func (f *Flagset) Uint64Flag(i *Uint64Flag) { + f.addFlag(&FlagVar{ + Name: i.Name, + Usage: i.Usage, + }) + f.set.Uint64Var(i.Value, i.Name, i.Default, i.Usage) +} + +type BigIntFlag struct { + Name string + Usage string + Value *big.Int +} + +func (b *BigIntFlag) String() string { + if b.Value == nil { + return "" + } + return b.Value.String() +} + +func (b *BigIntFlag) Set(value string) error { + num := new(big.Int) + + var ok bool + if strings.HasPrefix(value, "0x") { + num, ok = num.SetString(value[2:], 16) + } else { + num, ok = num.SetString(value, 10) + } + if !ok { + return fmt.Errorf("failed to set big int") + } + b.Value = num + return nil +} + +func (f *Flagset) BigIntFlag(b *BigIntFlag) { + f.addFlag(&FlagVar{ + Name: b.Name, + Usage: b.Usage, + }) + f.set.Var(b, b.Name, b.Usage) +} + +type SliceStringFlag struct { + Name string + Usage string + Value *[]string +} + +func (i *SliceStringFlag) String() string { + if i.Value == nil { + return "" + } + return strings.Join(*i.Value, ",") +} + +func (i *SliceStringFlag) Set(value string) error { + *i.Value = append(*i.Value, strings.Split(value, ",")...) + return nil +} + +func (f *Flagset) SliceStringFlag(s *SliceStringFlag) { + f.addFlag(&FlagVar{ + Name: s.Name, + Usage: s.Usage, + }) + f.set.Var(s, s.Name, s.Usage) +} + +type DurationFlag struct { + Name string + Usage string + Value *time.Duration + Default time.Duration +} + +func (f *Flagset) DurationFlag(d *DurationFlag) { + f.addFlag(&FlagVar{ + Name: d.Name, + Usage: d.Usage, + }) + f.set.DurationVar(d.Value, d.Name, d.Default, "") +} + +type MapStringFlag struct { + Name string + Usage string + Value *map[string]string +} + +func (m *MapStringFlag) String() string { + if m.Value == nil { + return "" + } + ls := []string{} + for k, v := range *m.Value { + ls = append(ls, k+"="+v) + } + return strings.Join(ls, ",") +} + +func (m *MapStringFlag) Set(value string) error { + if m.Value == nil { + m.Value = &map[string]string{} + } + for _, t := range strings.Split(value, ",") { + if t != "" { + kv := strings.Split(t, "=") + + if len(kv) == 2 { + (*m.Value)[kv[0]] = kv[1] + } + } + } + return nil +} + +func (f *Flagset) MapStringFlag(m *MapStringFlag) { + f.addFlag(&FlagVar{ + Name: m.Name, + Usage: m.Usage, + }) + f.set.Var(m, m.Name, m.Usage) +} + +type Float64Flag struct { + Name string + Usage string + Value *float64 + Default float64 +} + +func (f *Flagset) Float64Flag(i *Float64Flag) { + f.addFlag(&FlagVar{ + Name: i.Name, + Usage: i.Usage, + }) + f.set.Float64Var(i.Value, i.Name, i.Default, "") +} diff --git a/command/flagset/flagset_test.go b/command/flagset/flagset_test.go new file mode 100644 index 0000000000000000000000000000000000000000..2f046c32480458cd11f90459acf333816663b6b3 --- /dev/null +++ b/command/flagset/flagset_test.go @@ -0,0 +1,60 @@ +package flagset + +import ( + "testing" + "time" + + "github.com/stretchr/testify/assert" +) + +func TestFlagsetBool(t *testing.T) { + f := NewFlagSet("") + + value := false + f.BoolFlag(&BoolFlag{ + Name: "flag", + Value: &value, + }) + + assert.NoError(t, f.Parse([]string{"--flag", "true"})) + assert.Equal(t, value, true) +} + +func TestFlagsetSliceString(t *testing.T) { + f := NewFlagSet("") + + value := []string{} + f.SliceStringFlag(&SliceStringFlag{ + Name: "flag", + Value: &value, + }) + + assert.NoError(t, f.Parse([]string{"--flag", "a,b", "--flag", "c"})) + assert.Equal(t, value, []string{"a", "b", "c"}) +} + +func TestFlagsetDuration(t *testing.T) { + f := NewFlagSet("") + + value := time.Duration(0) + f.DurationFlag(&DurationFlag{ + Name: "flag", + Value: &value, + }) + + assert.NoError(t, f.Parse([]string{"--flag", "1m"})) + assert.Equal(t, value, 1*time.Minute) +} + +func TestFlagsetMapString(t *testing.T) { + f := NewFlagSet("") + + value := map[string]string{} + f.MapStringFlag(&MapStringFlag{ + Name: "flag", + Value: &value, + }) + + assert.NoError(t, f.Parse([]string{"--flag", "a=b,c=d"})) + assert.Equal(t, value, map[string]string{"a": "b", "c": "d"}) +} diff --git a/command/main.go b/command/main.go new file mode 100644 index 0000000000000000000000000000000000000000..7b276e703bb804d0d868b9587cbe83311001241d --- /dev/null +++ b/command/main.go @@ -0,0 +1,217 @@ +package main + +import ( + "fmt" + "os" + + "github.com/ethereum/go-ethereum/accounts/keystore" + "github.com/ethereum/go-ethereum/command/flagset" + "github.com/ethereum/go-ethereum/command/server" + "github.com/ethereum/go-ethereum/command/server/proto" + "github.com/ethereum/go-ethereum/node" + "github.com/mitchellh/cli" + "github.com/ryanuber/columnize" + "google.golang.org/grpc" +) + +func main() { + os.Exit(Run(os.Args[1:])) +} + +func Run(args []string) int { + commands := commands() + + cli := &cli.CLI{ + Name: "bor", + Args: args, + Commands: commands, + } + + exitCode, err := cli.Run() + if err != nil { + fmt.Fprintf(os.Stderr, "Error executing CLI: %s\n", err.Error()) + return 1 + } + return exitCode +} + +func commands() map[string]cli.CommandFactory { + ui := &cli.BasicUi{ + Reader: os.Stdin, + Writer: os.Stdout, + ErrorWriter: os.Stderr, + } + + meta2 := &Meta2{ + UI: ui, + } + meta := &Meta{ + UI: ui, + } + return map[string]cli.CommandFactory{ + "server": func() (cli.Command, error) { + return &server.Command{ + UI: ui, + }, nil + }, + "version": func() (cli.Command, error) { + return &VersionCommand{ + UI: ui, + }, nil + }, + "debug": func() (cli.Command, error) { + return &DebugCommand{ + Meta2: meta2, + }, nil + }, + "chain": func() (cli.Command, error) { + return &ChainCommand{ + UI: ui, + }, nil + }, + "chain sethead": func() (cli.Command, error) { + return &ChainSetHeadCommand{ + Meta2: meta2, + }, nil + }, + "account": func() (cli.Command, error) { + return &Account{ + UI: ui, + }, nil + }, + "account new": func() (cli.Command, error) { + return &AccountNewCommand{ + Meta: meta, + }, nil + }, + "account import": func() (cli.Command, error) { + return &AccountImportCommand{ + Meta: meta, + }, nil + }, + "account list": func() (cli.Command, error) { + return &AccountListCommand{ + Meta: meta, + }, nil + }, + "peers": func() (cli.Command, error) { + return &PeersCommand{ + UI: ui, + }, nil + }, + "peers add": func() (cli.Command, error) { + return &PeersAddCommand{ + Meta2: meta2, + }, nil + }, + "peers remove": func() (cli.Command, error) { + return &PeersRemoveCommand{ + Meta2: meta2, + }, nil + }, + "peers list": func() (cli.Command, error) { + return &PeersListCommand{ + Meta2: meta2, + }, nil + }, + "peers status": func() (cli.Command, error) { + return &PeersStatusCommand{ + Meta2: meta2, + }, nil + }, + } +} + +type Meta2 struct { + UI cli.Ui + + addr string +} + +func (m *Meta2) NewFlagSet(n string) *flagset.Flagset { + f := flagset.NewFlagSet(n) + + f.StringFlag(&flagset.StringFlag{ + Name: "address", + Value: &m.addr, + Usage: "Address of the grpc endpoint", + Default: "127.0.0.1:3131", + }) + return f +} + +func (m *Meta2) Conn() (*grpc.ClientConn, error) { + conn, err := grpc.Dial(m.addr, grpc.WithInsecure()) + if err != nil { + return nil, fmt.Errorf("failed to connect to server: %v", err) + } + return conn, nil +} + +func (m *Meta2) BorConn() (proto.BorClient, error) { + conn, err := m.Conn() + if err != nil { + return nil, err + } + return proto.NewBorClient(conn), nil +} + +// Meta is a helper utility for the commands +type Meta struct { + UI cli.Ui + + dataDir string + keyStoreDir string +} + +func (m *Meta) NewFlagSet(n string) *flagset.Flagset { + f := flagset.NewFlagSet(n) + + f.StringFlag(&flagset.StringFlag{ + Name: "datadir", + Value: &m.dataDir, + Usage: "Path of the data directory to store information", + }) + f.StringFlag(&flagset.StringFlag{ + Name: "keystore", + Value: &m.keyStoreDir, + Usage: "Path of the data directory to store information", + }) + + return f +} + +func (m *Meta) AskPassword() (string, error) { + return m.UI.AskSecret("Your new account is locked with a password. Please give a password. Do not forget this password") +} + +func (m *Meta) GetKeystore() (*keystore.KeyStore, error) { + cfg := node.DefaultConfig + cfg.DataDir = m.dataDir + cfg.KeyStoreDir = m.keyStoreDir + + stack, err := node.New(&cfg) + if err != nil { + return nil, err + } + + keydir := stack.KeyStoreDir() + scryptN := keystore.StandardScryptN + scryptP := keystore.StandardScryptP + + keys := keystore.NewKeyStore(keydir, scryptN, scryptP) + return keys, nil +} + +func formatList(in []string) string { + columnConf := columnize.DefaultConfig() + columnConf.Empty = "<none>" + return columnize.Format(in, columnConf) +} + +func formatKV(in []string) string { + columnConf := columnize.DefaultConfig() + columnConf.Empty = "<none>" + columnConf.Glue = " = " + return columnize.Format(in, columnConf) +} diff --git a/command/peers.go b/command/peers.go new file mode 100644 index 0000000000000000000000000000000000000000..bfe56842d95a0c89a4582bdd869568cad42e74b6 --- /dev/null +++ b/command/peers.go @@ -0,0 +1,43 @@ +package main + +import ( + "github.com/mitchellh/cli" +) + +// PeersCommand is the command to group the peers commands +type PeersCommand struct { + UI cli.Ui +} + +// Help implements the cli.Command interface +func (c *PeersCommand) Help() string { + return `Usage: bor peers <subcommand> + + This command groups actions to interact with peers. + + List the connected peers: + + $ bor account new + + Add a new peer by enode: + + $ bor account import + + Remove a connected peer by enode: + + $ bor peers remove <enode> + + Display information about a peer: + + $ bor peers status <peer id>` +} + +// Synopsis implements the cli.Command interface +func (c *PeersCommand) Synopsis() string { + return "Interact with peers" +} + +// Run implements the cli.Command interface +func (c *PeersCommand) Run(args []string) int { + return cli.RunResultHelp +} diff --git a/command/peers_add.go b/command/peers_add.go new file mode 100644 index 0000000000000000000000000000000000000000..796b8966819b8f3067b188760825a1a060f8ac65 --- /dev/null +++ b/command/peers_add.go @@ -0,0 +1,72 @@ +package main + +import ( + "context" + + "github.com/ethereum/go-ethereum/command/flagset" + "github.com/ethereum/go-ethereum/command/server/proto" +) + +// PeersAddCommand is the command to group the peers commands +type PeersAddCommand struct { + *Meta2 + + trusted bool +} + +// Help implements the cli.Command interface +func (p *PeersAddCommand) Help() string { + return `Usage: bor peers add <enode> + + Joins the local client to another remote peer. + + ` + p.Flags().Help() +} + +func (p *PeersAddCommand) Flags() *flagset.Flagset { + flags := p.NewFlagSet("peers add") + + flags.BoolFlag(&flagset.BoolFlag{ + Name: "trusted", + Usage: "Add the peer as a trusted", + Value: &p.trusted, + }) + + return flags +} + +// Synopsis implements the cli.Command interface +func (c *PeersAddCommand) Synopsis() string { + return "Join the client to a remote peer" +} + +// Run implements the cli.Command interface +func (c *PeersAddCommand) Run(args []string) int { + flags := c.Flags() + if err := flags.Parse(args); err != nil { + c.UI.Error(err.Error()) + return 1 + } + + args = flags.Args() + if len(args) != 1 { + c.UI.Error("No enode address provided") + return 1 + } + + borClt, err := c.BorConn() + if err != nil { + c.UI.Error(err.Error()) + return 1 + } + + req := &proto.PeersAddRequest{ + Enode: args[0], + Trusted: c.trusted, + } + if _, err := borClt.PeersAdd(context.Background(), req); err != nil { + c.UI.Error(err.Error()) + return 1 + } + return 0 +} diff --git a/command/peers_list.go b/command/peers_list.go new file mode 100644 index 0000000000000000000000000000000000000000..47e9e4caf0c34c543b49e047c4d0e6bad1225539 --- /dev/null +++ b/command/peers_list.go @@ -0,0 +1,81 @@ +package main + +import ( + "context" + "fmt" + "strings" + + "github.com/ethereum/go-ethereum/command/flagset" + "github.com/ethereum/go-ethereum/command/server/proto" +) + +// PeersListCommand is the command to group the peers commands +type PeersListCommand struct { + *Meta2 +} + +// Help implements the cli.Command interface +func (p *PeersListCommand) Help() string { + return `Usage: bor peers list + + Build an archive containing Bor pprof traces + + ` + p.Flags().Help() +} + +func (p *PeersListCommand) Flags() *flagset.Flagset { + flags := p.NewFlagSet("peers list") + + return flags +} + +// Synopsis implements the cli.Command interface +func (c *PeersListCommand) Synopsis() string { + return "" +} + +// Run implements the cli.Command interface +func (c *PeersListCommand) Run(args []string) int { + flags := c.Flags() + if err := flags.Parse(args); err != nil { + c.UI.Error(err.Error()) + return 1 + } + + borClt, err := c.BorConn() + if err != nil { + c.UI.Error(err.Error()) + return 1 + } + + req := &proto.PeersListRequest{} + resp, err := borClt.PeersList(context.Background(), req) + if err != nil { + c.UI.Error(err.Error()) + return 1 + } + + c.UI.Output(formatPeers(resp.Peers)) + return 0 +} + +func formatPeers(peers []*proto.Peer) string { + if len(peers) == 0 { + return "No peers found" + } + + rows := make([]string, len(peers)+1) + rows[0] = "ID|Enode|Name|Caps|Static|Trusted" + for i, d := range peers { + enode := strings.TrimPrefix(d.Enode, "enode://") + + rows[i+1] = fmt.Sprintf("%s|%s|%s|%s|%v|%v", + d.Id, + enode[:10], + d.Name, + strings.Join(d.Caps, ","), + d.Static, + d.Trusted) + } + return formatList(rows) +} diff --git a/command/peers_remove.go b/command/peers_remove.go new file mode 100644 index 0000000000000000000000000000000000000000..432a35fdcb0869987d3a7386fa463554ce7bffc4 --- /dev/null +++ b/command/peers_remove.go @@ -0,0 +1,72 @@ +package main + +import ( + "context" + + "github.com/ethereum/go-ethereum/command/flagset" + "github.com/ethereum/go-ethereum/command/server/proto" +) + +// PeersRemoveCommand is the command to group the peers commands +type PeersRemoveCommand struct { + *Meta2 + + trusted bool +} + +// Help implements the cli.Command interface +func (p *PeersRemoveCommand) Help() string { + return `Usage: bor peers remove <enode> + + Disconnects the local client from a connected peer if exists. + + ` + p.Flags().Help() +} + +func (p *PeersRemoveCommand) Flags() *flagset.Flagset { + flags := p.NewFlagSet("peers remove") + + flags.BoolFlag(&flagset.BoolFlag{ + Name: "trusted", + Usage: "Add the peer as a trusted", + Value: &p.trusted, + }) + + return flags +} + +// Synopsis implements the cli.Command interface +func (c *PeersRemoveCommand) Synopsis() string { + return "Disconnects a peer from the client" +} + +// Run implements the cli.Command interface +func (c *PeersRemoveCommand) Run(args []string) int { + flags := c.Flags() + if err := flags.Parse(args); err != nil { + c.UI.Error(err.Error()) + return 1 + } + + args = flags.Args() + if len(args) != 1 { + c.UI.Error("No enode address provided") + return 1 + } + + borClt, err := c.BorConn() + if err != nil { + c.UI.Error(err.Error()) + return 1 + } + + req := &proto.PeersRemoveRequest{ + Enode: args[0], + Trusted: c.trusted, + } + if _, err := borClt.PeersRemove(context.Background(), req); err != nil { + c.UI.Error(err.Error()) + return 1 + } + return 0 +} diff --git a/command/peers_status.go b/command/peers_status.go new file mode 100644 index 0000000000000000000000000000000000000000..adb7b2e850ecda1537a65a6f5d1ef7be87ca4721 --- /dev/null +++ b/command/peers_status.go @@ -0,0 +1,81 @@ +package main + +import ( + "context" + "fmt" + "strings" + + "github.com/ethereum/go-ethereum/command/flagset" + "github.com/ethereum/go-ethereum/command/server/proto" +) + +// PeersStatusCommand is the command to group the peers commands +type PeersStatusCommand struct { + *Meta2 +} + +// Help implements the cli.Command interface +func (p *PeersStatusCommand) Help() string { + return `Usage: bor peers status <peer id> + + Display the status of a peer by its id. + + ` + p.Flags().Help() +} + +func (p *PeersStatusCommand) Flags() *flagset.Flagset { + flags := p.NewFlagSet("peers status") + + return flags +} + +// Synopsis implements the cli.Command interface +func (c *PeersStatusCommand) Synopsis() string { + return "Display the status of a peer" +} + +// Run implements the cli.Command interface +func (c *PeersStatusCommand) Run(args []string) int { + flags := c.Flags() + if err := flags.Parse(args); err != nil { + c.UI.Error(err.Error()) + return 1 + } + + args = flags.Args() + if len(args) != 1 { + c.UI.Error("No enode address provided") + return 1 + } + + borClt, err := c.BorConn() + if err != nil { + c.UI.Error(err.Error()) + return 1 + } + + req := &proto.PeersStatusRequest{ + Enode: args[0], + } + resp, err := borClt.PeersStatus(context.Background(), req) + if err != nil { + c.UI.Error(err.Error()) + return 1 + } + + c.UI.Output(formatPeer(resp.Peer)) + return 0 +} + +func formatPeer(peer *proto.Peer) string { + base := formatKV([]string{ + fmt.Sprintf("Name|%s", peer.Name), + fmt.Sprintf("ID|%s", peer.Id), + fmt.Sprintf("ENR|%s", peer.Enr), + fmt.Sprintf("Capabilities|%s", strings.Join(peer.Caps, ",")), + fmt.Sprintf("Enode|%s", peer.Enode), + fmt.Sprintf("Static|%v", peer.Static), + fmt.Sprintf("Trusted|%v", peer.Trusted), + }) + return base +} diff --git a/command/server/chains/allocs/mainnet.json b/command/server/chains/allocs/mainnet.json new file mode 100644 index 0000000000000000000000000000000000000000..897fb053bf2df069c542faf53897093dd10d092f --- /dev/null +++ b/command/server/chains/allocs/mainnet.json @@ -0,0 +1,35 @@ +{ + "0000000000000000000000000000000000001000": { + "balance": "0x0", + "code": "0x608060405234801561001057600080fd5b50600436106101f05760003560e01c806360c8614d1161010f578063af26aa96116100a2578063d5b844eb11610071578063d5b844eb14610666578063dcf2793a14610684578063e3b7c924146106b6578063f59cf565146106d4576101f0565b8063af26aa96146105c7578063b71d7a69146105e7578063b7ab4db514610617578063c1b3c91914610636576101f0565b806370ba5707116100de57806370ba57071461052b57806398ab2b621461055b5780639d11b80714610579578063ae756451146105a9576101f0565b806360c8614d1461049c57806365b3a1e2146104bc57806366332354146104db578063687a9bd6146104f9576101f0565b80633434735f1161018757806344d6528f1161015657806344d6528f146103ee5780634dbc959f1461041e57806355614fcc1461043c578063582a8d081461046c576101f0565b80633434735f1461035257806335ddfeea1461037057806343ee8213146103a057806344c15cb1146103be576101f0565b806323f2a73f116101c357806323f2a73f146102a45780632bc06564146102d45780632de3a180146102f25780632eddf35214610322576101f0565b8063047a6c5b146101f55780630c35b1cb146102275780631270b5741461025857806323c2a2b414610288575b600080fd5b61020f600480360361020a9190810190612c14565b610706565b60405161021e93929190613553565b60405180910390f35b610241600480360361023c9190810190612c14565b61075d565b60405161024f929190613374565b60405180910390f35b610272600480360361026d9190810190612c3d565b610939565b60405161027f91906133ab565b60405180910390f35b6102a2600480360361029d9190810190612d1c565b610a91565b005b6102be60048036036102b99190810190612c3d565b61112a565b6040516102cb91906133ab565b60405180910390f35b6102dc611281565b6040516102e99190613501565b60405180910390f35b61030c60048036036103079190810190612b71565b611286565b60405161031991906133c6565b60405180910390f35b61033c60048036036103379190810190612c14565b611307565b6040516103499190613501565b60405180910390f35b61035a611437565b6040516103679190613359565b60405180910390f35b61038a60048036036103859190810190612bad565b61144f565b60405161039791906133ab565b60405180910390f35b6103a861151a565b6040516103b591906133c6565b60405180910390f35b6103d860048036036103d39190810190612c79565b611531565b6040516103e59190613501565b60405180910390f35b61040860048036036104039190810190612c3d565b611619565b60405161041591906134e6565b60405180910390f35b610426611781565b6040516104339190613501565b60405180910390f35b61045660048036036104519190810190612af6565b611791565b60405161046391906133ab565b60405180910390f35b61048660048036036104819190810190612b1f565b6117ab565b60405161049391906133c6565b60405180910390f35b6104a4611829565b6040516104b393929190613553565b60405180910390f35b6104c461189d565b6040516104d2929190613374565b60405180910390f35b6104e3611c5e565b6040516104f09190613501565b60405180910390f35b610513600480360361050e9190810190612ce0565b611c63565b6040516105229392919061351c565b60405180910390f35b61054560048036036105409190810190612af6565b611cc7565b60405161055291906133ab565b60405180910390f35b610563611ce1565b60405161057091906133c6565b60405180910390f35b610593600480360361058e9190810190612c14565b611cf8565b6040516105a09190613501565b60405180910390f35b6105b1611e29565b6040516105be91906133c6565b60405180910390f35b6105cf611e40565b6040516105de93929190613553565b60405180910390f35b61060160048036036105fc9190810190612c14565b611ea1565b60405161060e9190613501565b60405180910390f35b61061f611fa1565b60405161062d929190613374565b60405180910390f35b610650600480360361064b9190810190612c14565b611fb5565b60405161065d9190613501565b60405180910390f35b61066e611fd6565b60405161067b919061358a565b60405180910390f35b61069e60048036036106999190810190612ce0565b611fdb565b6040516106ad9392919061351c565b60405180910390f35b6106be61203f565b6040516106cb9190613501565b60405180910390f35b6106ee60048036036106e99190810190612c14565b612051565b6040516106fd93929190613553565b60405180910390f35b60008060006002600085815260200190815260200160002060000154600260008681526020019081526020016000206001015460026000878152602001908152602001600020600201549250925092509193909250565b60608060ff83116107795761077061189d565b91509150610934565b600061078484611ea1565b9050606060016000838152602001908152602001600020805490506040519080825280602002602001820160405280156107cd5781602001602082028038833980820191505090505b509050606060016000848152602001908152602001600020805490506040519080825280602002602001820160405280156108175781602001602082028038833980820191505090505b50905060008090505b60016000858152602001908152602001600020805490508110156109295760016000858152602001908152602001600020818154811061085c57fe5b906000526020600020906003020160020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1683828151811061089a57fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250506001600085815260200190815260200160002081815481106108f257fe5b90600052602060002090600302016001015482828151811061091057fe5b6020026020010181815250508080600101915050610820565b508181945094505050505b915091565b6000606060016000858152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b82821015610a0c578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152505081526020019060010190610970565b50505050905060008090505b8151811015610a84578373ffffffffffffffffffffffffffffffffffffffff16828281518110610a4457fe5b60200260200101516040015173ffffffffffffffffffffffffffffffffffffffff161415610a7757600192505050610a8b565b8080600101915050610a18565b5060009150505b92915050565b73fffffffffffffffffffffffffffffffffffffffe73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610b13576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b0a906134c6565b60405180910390fd5b6000610b1d611781565b90506000811415610b3157610b3061207b565b5b610b4560018261239c90919063ffffffff16565b8814610b86576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b7d90613446565b60405180910390fd5b868611610bc8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bbf906134a6565b60405180910390fd5b6000604060018989030181610bd957fe5b0614610c1a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c1190613486565b60405180910390fd5b8660026000838152602001908152602001600020600101541115610c73576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c6a90613426565b60405180910390fd5b6000600260008a81526020019081526020016000206000015414610ccc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cc390613466565b60405180910390fd5b604051806060016040528089815260200188815260200187815250600260008a8152602001908152602001600020600082015181600001556020820151816001015560408201518160020155905050600388908060018154018082558091505090600182039060005260206000200160009091929091909150555060008060008a815260200190815260200160002081610d6691906128f0565b506000600160008a815260200190815260200160002081610d8791906128f0565b506060610ddf610dda87878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506123bb565b6123e9565b905060008090505b8151811015610f51576060610e0e838381518110610e0157fe5b60200260200101516123e9565b90506000808c81526020019081526020016000208054809190600101610e3491906128f0565b506040518060600160405280610e5d83600081518110610e5057fe5b60200260200101516124c6565b8152602001610e7f83600181518110610e7257fe5b60200260200101516124c6565b8152602001610ea183600281518110610e9457fe5b6020026020010151612537565b73ffffffffffffffffffffffffffffffffffffffff168152506000808d81526020019081526020016000208381548110610ed757fe5b9060005260206000209060030201600082015181600001556020820151816001015560408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550905050508080600101915050610de7565b506060610fa9610fa486868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506123bb565b6123e9565b905060008090505b815181101561111d576060610fd8838381518110610fcb57fe5b60200260200101516123e9565b9050600160008d81526020019081526020016000208054809190600101610fff91906128f0565b5060405180606001604052806110288360008151811061101b57fe5b60200260200101516124c6565b815260200161104a8360018151811061103d57fe5b60200260200101516124c6565b815260200161106c8360028151811061105f57fe5b6020026020010151612537565b73ffffffffffffffffffffffffffffffffffffffff16815250600160008e815260200190815260200160002083815481106110a357fe5b9060005260206000209060030201600082015181600001556020820151816001015560408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550905050508080600101915050610fb1565b5050505050505050505050565b60006060600080858152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b828210156111fc578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152505081526020019060010190611160565b50505050905060008090505b8151811015611274578373ffffffffffffffffffffffffffffffffffffffff1682828151811061123457fe5b60200260200101516040015173ffffffffffffffffffffffffffffffffffffffff1614156112675760019250505061127b565b8080600101915050611208565b5060009150505b92915050565b604081565b60006002600160f81b84846040516020016112a3939291906132c6565b6040516020818303038152906040526040516112bf9190613303565b602060405180830381855afa1580156112dc573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052506112ff9190810190612b48565b905092915050565b60006060600080848152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b828210156113d9578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815250508152602001906001019061133d565b505050509050600080905060008090505b825181101561142c5761141d83828151811061140257fe5b6020026020010151602001518361239c90919063ffffffff16565b915080806001019150506113ea565b508092505050919050565b73fffffffffffffffffffffffffffffffffffffffe81565b600080600080859050600060218087518161146657fe5b04029050600081111561147f5761147c876117ab565b91505b6000602190505b818111611509576000600182038801519050818801519550806000602081106114ab57fe5b1a60f81b9450600060f81b857effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614156114f0576114e98685611286565b93506114fd565b6114fa8487611286565b93505b50602181019050611486565b508782149450505050509392505050565b60405161152690613344565b604051809103902081565b60008060009050600080905060008090505b84518167ffffffffffffffff16101561160c57606061156e868367ffffffffffffffff16604161255a565b9050600061158582896125e690919063ffffffff16565b905061158f612922565b6115998a83611619565b90506115a58a8361112a565b80156115dc57508473ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16115b156115fe578194506115fb81602001518761239c90919063ffffffff16565b95505b505050604181019050611543565b5081925050509392505050565b611621612922565b6060600080858152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b828210156116f1578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152505081526020019060010190611655565b50505050905060008090505b8151811015611779578373ffffffffffffffffffffffffffffffffffffffff1682828151811061172957fe5b60200260200101516040015173ffffffffffffffffffffffffffffffffffffffff16141561176c5781818151811061175d57fe5b60200260200101519250611779565b80806001019150506116fd565b505092915050565b600061178c43611ea1565b905090565b60006117a461179e611781565b8361112a565b9050919050565b60006002600060f81b836040516020016117c692919061329a565b6040516020818303038152906040526040516117e29190613303565b602060405180830381855afa1580156117ff573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052506118229190810190612b48565b9050919050565b60008060008061184a600161183c611781565b61239c90919063ffffffff16565b905060026000828152602001908152602001600020600001546002600083815260200190815260200160002060010154600260008481526020019081526020016000206002015493509350935050909192565b606080606060076040519080825280602002602001820160405280156118d25781602001602082028038833980820191505090505b509050735973918275c01f50555d44e92c9d9b353cadad54816000815181106118f757fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505073b8bb158b93c94ed35c1970d610d1e2b34e26652c8160018151811061195357fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505073f84c74dea96df0ec22e11e7c33996c73fcc2d822816002815181106119af57fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505073b702f1c9154ac9c08da247a8e30ee6f2f3373f4181600381518110611a0b57fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050737fcd58c2d53d980b247f1612fdba93e9a76193e681600481518110611a6757fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050730375b2fc7140977c9c76d45421564e354ed4227781600581518110611ac357fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250507342eefcda06ead475cde3731b8eb138e88cd0bac381600681518110611b1f57fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060606007604051908082528060200260200182016040528015611b8b5781602001602082028038833980820191505090505b50905061271081600081518110611b9e57fe5b60200260200101818152505061271081600181518110611bba57fe5b60200260200101818152505061271081600281518110611bd657fe5b60200260200101818152505061271081600381518110611bf257fe5b60200260200101818152505061271081600481518110611c0e57fe5b60200260200101818152505061271081600581518110611c2a57fe5b60200260200101818152505061271081600681518110611c4657fe5b60200260200101818152505081819350935050509091565b60ff81565b60016020528160005260406000208181548110611c7c57fe5b9060005260206000209060030201600091509150508060000154908060010154908060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905083565b6000611cda611cd4611781565b83610939565b9050919050565b604051611ced9061331a565b604051809103902081565b6000606060016000848152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b82821015611dcb578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152505081526020019060010190611d2f565b505050509050600080905060008090505b8251811015611e1e57611e0f838281518110611df457fe5b6020026020010151602001518361239c90919063ffffffff16565b91508080600101915050611ddc565b508092505050919050565b604051611e359061332f565b604051809103902081565b600080600080611e4e611781565b905060026000828152602001908152602001600020600001546002600083815260200190815260200160002060010154600260008481526020019081526020016000206002015493509350935050909192565b60008060038054905090505b6000811115611f6157611ebe612959565b6002600060036001850381548110611ed257fe5b906000526020600020015481526020019081526020016000206040518060600160405290816000820154815260200160018201548152602001600282015481525050905083816020015111158015611f2f57506000816040015114155b8015611f3f575080604001518411155b15611f5257806000015192505050611f9c565b50808060019003915050611ead565b5060006003805490501115611f9757600360016003805490500381548110611f8557fe5b90600052602060002001549050611f9c565b600090505b919050565b606080611fad4361075d565b915091509091565b60038181548110611fc257fe5b906000526020600020016000915090505481565b600281565b60006020528160005260406000208181548110611ff457fe5b9060005260206000209060030201600091509150508060000154908060010154908060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905083565b60006040438161204b57fe5b04905090565b60026020528060005260406000206000915090508060000154908060010154908060020154905083565b60608061208661189d565b8092508193505050600080905060405180606001604052808281526020016000815260200160ff81525060026000838152602001908152602001600020600082015181600001556020820151816001015560408201518160020155905050600381908060018154018082558091505090600182039060005260206000200160009091929091909150555060008060008381526020019081526020016000208161212f91906128f0565b506000600160008381526020019081526020016000208161215091906128f0565b5060008090505b835181101561227257600080838152602001908152602001600020805480919060010161218491906128f0565b5060405180606001604052808281526020018483815181106121a257fe5b602002602001015181526020018583815181106121bb57fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681525060008084815260200190815260200160002082815481106121f957fe5b9060005260206000209060030201600082015181600001556020820151816001015560408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055509050508080600101915050612157565b5060008090505b8351811015612396576001600083815260200190815260200160002080548091906001016122a791906128f0565b5060405180606001604052808281526020018483815181106122c557fe5b602002602001015181526020018583815181106122de57fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681525060016000848152602001908152602001600020828154811061231d57fe5b9060005260206000209060030201600082015181600001556020820151816001015560408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055509050508080600101915050612279565b50505050565b6000808284019050838110156123b157600080fd5b8091505092915050565b6123c361297a565b600060208301905060405180604001604052808451815260200182815250915050919050565b60606123f4826126f0565b6123fd57600080fd5b60006124088361273e565b905060608160405190808252806020026020018201604052801561244657816020015b612433612994565b81526020019060019003908161242b5790505b509050600061245885602001516127af565b8560200151019050600080600090505b848110156124b95761247983612838565b915060405180604001604052808381526020018481525084828151811061249c57fe5b602002602001018190525081830192508080600101915050612468565b5082945050505050919050565b60008082600001511180156124e057506021826000015111155b6124e957600080fd5b60006124f883602001516127af565b9050600081846000015103905060008083866020015101905080519150602083101561252b57826020036101000a820491505b81945050505050919050565b6000601582600001511461254a57600080fd5b612553826124c6565b9050919050565b60608183018451101561256c57600080fd5b6060821560008114612589576040519150602082016040526125da565b6040519150601f8416801560200281840101858101878315602002848b0101015b818310156125c757805183526020830192506020810190506125aa565b50868552601f19601f8301166040525050505b50809150509392505050565b600080600080604185511461260157600093505050506126ea565b602085015192506040850151915060ff6041860151169050601b8160ff16101561262c57601b810190505b601b8160ff16141580156126445750601c8160ff1614155b1561265557600093505050506126ea565b60006001878386866040516000815260200160405260405161267a94939291906133e1565b6020604051602081039080840390855afa15801561269c573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156126e257600080fd5b809450505050505b92915050565b600080826000015114156127075760009050612739565b60008083602001519050805160001a915060c060ff168260ff16101561273257600092505050612739565b6001925050505b919050565b6000808260000151141561275557600090506127aa565b6000809050600061276984602001516127af565b84602001510190506000846000015185602001510190505b808210156127a35761279282612838565b820191508280600101935050612781565b8293505050505b919050565b600080825160001a9050608060ff168110156127cf576000915050612833565b60b860ff168110806127f4575060c060ff1681101580156127f3575060f860ff1681105b5b15612803576001915050612833565b60c060ff168110156128235760018060b80360ff16820301915050612833565b60018060f80360ff168203019150505b919050565b6000806000835160001a9050608060ff1681101561285957600191506128e6565b60b860ff16811015612876576001608060ff1682030191506128e5565b60c060ff168110156128a65760b78103600185019450806020036101000a855104600182018101935050506128e4565b60f860ff168110156128c357600160c060ff1682030191506128e3565b60f78103600185019450806020036101000a855104600182018101935050505b5b5b5b8192505050919050565b81548183558181111561291d5760030281600302836000526020600020918201910161291c91906129ae565b5b505050565b60405180606001604052806000815260200160008152602001600073ffffffffffffffffffffffffffffffffffffffff1681525090565b60405180606001604052806000815260200160008152602001600081525090565b604051806040016040528060008152602001600081525090565b604051806040016040528060008152602001600081525090565b612a0191905b808211156129fd5760008082016000905560018201600090556002820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055506003016129b4565b5090565b90565b600081359050612a1381613783565b92915050565b600081359050612a288161379a565b92915050565b600081519050612a3d8161379a565b92915050565b60008083601f840112612a5557600080fd5b8235905067ffffffffffffffff811115612a6e57600080fd5b602083019150836001820283011115612a8657600080fd5b9250929050565b600082601f830112612a9e57600080fd5b8135612ab1612aac826135d2565b6135a5565b91508082526020830160208301858383011115612acd57600080fd5b612ad883828461372d565b50505092915050565b600081359050612af0816137b1565b92915050565b600060208284031215612b0857600080fd5b6000612b1684828501612a04565b91505092915050565b600060208284031215612b3157600080fd5b6000612b3f84828501612a19565b91505092915050565b600060208284031215612b5a57600080fd5b6000612b6884828501612a2e565b91505092915050565b60008060408385031215612b8457600080fd5b6000612b9285828601612a19565b9250506020612ba385828601612a19565b9150509250929050565b600080600060608486031215612bc257600080fd5b6000612bd086828701612a19565b9350506020612be186828701612a19565b925050604084013567ffffffffffffffff811115612bfe57600080fd5b612c0a86828701612a8d565b9150509250925092565b600060208284031215612c2657600080fd5b6000612c3484828501612ae1565b91505092915050565b60008060408385031215612c5057600080fd5b6000612c5e85828601612ae1565b9250506020612c6f85828601612a04565b9150509250929050565b600080600060608486031215612c8e57600080fd5b6000612c9c86828701612ae1565b9350506020612cad86828701612a19565b925050604084013567ffffffffffffffff811115612cca57600080fd5b612cd686828701612a8d565b9150509250925092565b60008060408385031215612cf357600080fd5b6000612d0185828601612ae1565b9250506020612d1285828601612ae1565b9150509250929050565b600080600080600080600060a0888a031215612d3757600080fd5b6000612d458a828b01612ae1565b9750506020612d568a828b01612ae1565b9650506040612d678a828b01612ae1565b955050606088013567ffffffffffffffff811115612d8457600080fd5b612d908a828b01612a43565b9450945050608088013567ffffffffffffffff811115612daf57600080fd5b612dbb8a828b01612a43565b925092505092959891949750929550565b6000612dd88383612dfc565b60208301905092915050565b6000612df0838361326d565b60208301905092915050565b612e05816136a2565b82525050565b612e14816136a2565b82525050565b6000612e258261361e565b612e2f8185613659565b9350612e3a836135fe565b8060005b83811015612e6b578151612e528882612dcc565b9750612e5d8361363f565b925050600181019050612e3e565b5085935050505092915050565b6000612e8382613629565b612e8d818561366a565b9350612e988361360e565b8060005b83811015612ec9578151612eb08882612de4565b9750612ebb8361364c565b925050600181019050612e9c565b5085935050505092915050565b612edf816136b4565b82525050565b612ef6612ef1826136c0565b61376f565b82525050565b612f05816136ec565b82525050565b612f1c612f17826136ec565b613779565b82525050565b6000612f2d82613634565b612f37818561367b565b9350612f4781856020860161373c565b80840191505092915050565b6000612f60600483613697565b91507f766f7465000000000000000000000000000000000000000000000000000000006000830152600482019050919050565b6000612fa0602d83613686565b91507f537461727420626c6f636b206d7573742062652067726561746572207468616e60008301527f2063757272656e74207370616e000000000000000000000000000000000000006020830152604082019050919050565b6000613006600383613697565b91507f31333700000000000000000000000000000000000000000000000000000000006000830152600382019050919050565b6000613046600f83613686565b91507f496e76616c6964207370616e20696400000000000000000000000000000000006000830152602082019050919050565b6000613086601383613686565b91507f5370616e20616c726561647920657869737473000000000000000000000000006000830152602082019050919050565b60006130c6604583613686565b91507f446966666572656e6365206265747765656e20737461727420616e6420656e6460008301527f20626c6f636b206d75737420626520696e206d756c7469706c6573206f66207360208301527f7072696e740000000000000000000000000000000000000000000000000000006040830152606082019050919050565b6000613152600c83613697565b91507f6865696d64616c6c2d31333700000000000000000000000000000000000000006000830152600c82019050919050565b6000613192602a83613686565b91507f456e6420626c6f636b206d7573742062652067726561746572207468616e207360008301527f7461727420626c6f636b000000000000000000000000000000000000000000006020830152604082019050919050565b60006131f8601283613686565b91507f4e6f742053797374656d204164646573732100000000000000000000000000006000830152602082019050919050565b606082016000820151613241600085018261326d565b506020820151613254602085018261326d565b5060408201516132676040850182612dfc565b50505050565b61327681613716565b82525050565b61328581613716565b82525050565b61329481613720565b82525050565b60006132a68285612ee5565b6001820191506132b68284612f0b565b6020820191508190509392505050565b60006132d28286612ee5565b6001820191506132e28285612f0b565b6020820191506132f28284612f0b565b602082019150819050949350505050565b600061330f8284612f22565b915081905092915050565b600061332582612f53565b9150819050919050565b600061333a82612ff9565b9150819050919050565b600061334f82613145565b9150819050919050565b600060208201905061336e6000830184612e0b565b92915050565b6000604082019050818103600083015261338e8185612e1a565b905081810360208301526133a28184612e78565b90509392505050565b60006020820190506133c06000830184612ed6565b92915050565b60006020820190506133db6000830184612efc565b92915050565b60006080820190506133f66000830187612efc565b613403602083018661328b565b6134106040830185612efc565b61341d6060830184612efc565b95945050505050565b6000602082019050818103600083015261343f81612f93565b9050919050565b6000602082019050818103600083015261345f81613039565b9050919050565b6000602082019050818103600083015261347f81613079565b9050919050565b6000602082019050818103600083015261349f816130b9565b9050919050565b600060208201905081810360008301526134bf81613185565b9050919050565b600060208201905081810360008301526134df816131eb565b9050919050565b60006060820190506134fb600083018461322b565b92915050565b6000602082019050613516600083018461327c565b92915050565b6000606082019050613531600083018661327c565b61353e602083018561327c565b61354b6040830184612e0b565b949350505050565b6000606082019050613568600083018661327c565b613575602083018561327c565b613582604083018461327c565b949350505050565b600060208201905061359f600083018461328b565b92915050565b6000604051905081810181811067ffffffffffffffff821117156135c857600080fd5b8060405250919050565b600067ffffffffffffffff8211156135e957600080fd5b601f19601f8301169050602081019050919050565b6000819050602082019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b60006136ad826136f6565b9050919050565b60008115159050919050565b60007fff0000000000000000000000000000000000000000000000000000000000000082169050919050565b6000819050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b82818337600083830152505050565b60005b8381101561375a57808201518184015260208101905061373f565b83811115613769576000848401525b50505050565b6000819050919050565b6000819050919050565b61378c816136a2565b811461379757600080fd5b50565b6137a3816136ec565b81146137ae57600080fd5b50565b6137ba81613716565b81146137c557600080fd5b5056fea365627a7a72315820638c74b73aaddeb2f2fb9267028e09737291458f6da93b6619d30c86432701d96c6578706572696d656e74616cf564736f6c634300050b0040" + }, + "0000000000000000000000000000000000001001": { + "balance": "0x0", + "code": "0x608060405234801561001057600080fd5b50600436106100415760003560e01c806319494a17146100465780633434735f146100e15780635407ca671461012b575b600080fd5b6100c76004803603604081101561005c57600080fd5b81019080803590602001909291908035906020019064010000000081111561008357600080fd5b82018360208201111561009557600080fd5b803590602001918460018302840111640100000000831117156100b757600080fd5b9091929391929390505050610149565b604051808215151515815260200191505060405180910390f35b6100e961047a565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610133610492565b6040518082815260200191505060405180910390f35b600073fffffffffffffffffffffffffffffffffffffffe73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610200576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f4e6f742053797374656d2041646465737321000000000000000000000000000081525060200191505060405180910390fd5b606061025761025285858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610498565b6104c6565b905060006102788260008151811061026b57fe5b60200260200101516105a3565b905080600160005401146102f4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f537461746549647320617265206e6f742073657175656e7469616c000000000081525060200191505060405180910390fd5b600080815480929190600101919050555060006103248360018151811061031757fe5b6020026020010151610614565b905060606103458460028151811061033857fe5b6020026020010151610637565b9050610350826106c3565b1561046f576000624c4b409050606084836040516024018083815260200180602001828103825283818151815260200191508051906020019080838360005b838110156103aa57808201518184015260208101905061038f565b50505050905090810190601f1680156103d75780820380516001836020036101000a031916815260200191505b5093505050506040516020818303038152906040527f26c53bea000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050905060008082516020840160008887f1965050505b505050509392505050565b73fffffffffffffffffffffffffffffffffffffffe81565b60005481565b6104a0610943565b600060208301905060405180604001604052808451815260200182815250915050919050565b60606104d1826106dc565b6104da57600080fd5b60006104e58361072a565b905060608160405190808252806020026020018201604052801561052357816020015b61051061095d565b8152602001906001900390816105085790505b5090506000610535856020015161079b565b8560200151019050600080600090505b848110156105965761055683610824565b915060405180604001604052808381526020018481525084828151811061057957fe5b602002602001018190525081830192508080600101915050610545565b5082945050505050919050565b60008082600001511180156105bd57506021826000015111155b6105c657600080fd5b60006105d5836020015161079b565b9050600081846000015103905060008083866020015101905080519150602083101561060857826020036101000a820491505b81945050505050919050565b6000601582600001511461062757600080fd5b610630826105a3565b9050919050565b6060600082600001511161064a57600080fd5b6000610659836020015161079b565b905060008184600001510390506060816040519080825280601f01601f19166020018201604052801561069b5781602001600182028038833980820191505090505b50905060008160200190506106b78487602001510182856108dc565b81945050505050919050565b600080823b905060008163ffffffff1611915050919050565b600080826000015114156106f35760009050610725565b60008083602001519050805160001a915060c060ff168260ff16101561071e57600092505050610725565b6001925050505b919050565b600080826000015114156107415760009050610796565b60008090506000610755846020015161079b565b84602001510190506000846000015185602001510190505b8082101561078f5761077e82610824565b82019150828060010193505061076d565b8293505050505b919050565b600080825160001a9050608060ff168110156107bb57600091505061081f565b60b860ff168110806107e0575060c060ff1681101580156107df575060f860ff1681105b5b156107ef57600191505061081f565b60c060ff1681101561080f5760018060b80360ff1682030191505061081f565b60018060f80360ff168203019150505b919050565b6000806000835160001a9050608060ff1681101561084557600191506108d2565b60b860ff16811015610862576001608060ff1682030191506108d1565b60c060ff168110156108925760b78103600185019450806020036101000a855104600182018101935050506108d0565b60f860ff168110156108af57600160c060ff1682030191506108cf565b60f78103600185019450806020036101000a855104600182018101935050505b5b5b5b8192505050919050565b60008114156108ea5761093e565b5b602060ff16811061091a5782518252602060ff1683019250602060ff1682019150602060ff16810390506108eb565b6000600182602060ff16036101000a03905080198451168184511681811785525050505b505050565b604051806040016040528060008152602001600081525090565b60405180604001604052806000815260200160008152509056fea265627a7a7231582083fbdacb76f32b4112d0f7db9a596937925824798a0026ba0232322390b5263764736f6c634300050b0032" + }, + "0000000000000000000000000000000000001010": { + "balance": "0x204fcce2c5a141f7f9a00000", + "code": "0x60806040526004361061019c5760003560e01c806377d32e94116100ec578063acd06cb31161008a578063e306f77911610064578063e306f77914610a7b578063e614d0d614610aa6578063f2fde38b14610ad1578063fc0c546a14610b225761019c565b8063acd06cb31461097a578063b789543c146109cd578063cc79f97b14610a505761019c565b80639025e64c116100c65780639025e64c146107c957806395d89b4114610859578063a9059cbb146108e9578063abceeba21461094f5761019c565b806377d32e94146106315780638da5cb5b146107435780638f32d59b1461079a5761019c565b806347e7ef24116101595780637019d41a116101335780637019d41a1461053357806370a082311461058a578063715018a6146105ef578063771282f6146106065761019c565b806347e7ef2414610410578063485cc9551461046b57806360f96a8f146104dc5761019c565b806306fdde03146101a15780631499c5921461023157806318160ddd1461028257806319d27d9c146102ad5780632e1a7d4d146103b1578063313ce567146103df575b600080fd5b3480156101ad57600080fd5b506101b6610b79565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101f65780820151818401526020810190506101db565b50505050905090810190601f1680156102235780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561023d57600080fd5b506102806004803603602081101561025457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610bb6565b005b34801561028e57600080fd5b50610297610c24565b6040518082815260200191505060405180910390f35b3480156102b957600080fd5b5061036f600480360360a08110156102d057600080fd5b81019080803590602001906401000000008111156102ed57600080fd5b8201836020820111156102ff57600080fd5b8035906020019184600183028401116401000000008311171561032157600080fd5b9091929391929390803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610c3a565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6103dd600480360360208110156103c757600080fd5b8101908080359060200190929190505050610e06565b005b3480156103eb57600080fd5b506103f4610f58565b604051808260ff1660ff16815260200191505060405180910390f35b34801561041c57600080fd5b506104696004803603604081101561043357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610f61565b005b34801561047757600080fd5b506104da6004803603604081101561048e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061111d565b005b3480156104e857600080fd5b506104f16111ec565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561053f57600080fd5b50610548611212565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561059657600080fd5b506105d9600480360360208110156105ad57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611238565b6040518082815260200191505060405180910390f35b3480156105fb57600080fd5b50610604611259565b005b34801561061257600080fd5b5061061b611329565b6040518082815260200191505060405180910390f35b34801561063d57600080fd5b506107016004803603604081101561065457600080fd5b81019080803590602001909291908035906020019064010000000081111561067b57600080fd5b82018360208201111561068d57600080fd5b803590602001918460018302840111640100000000831117156106af57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929050505061132f565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561074f57600080fd5b506107586114b4565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156107a657600080fd5b506107af6114dd565b604051808215151515815260200191505060405180910390f35b3480156107d557600080fd5b506107de611534565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561081e578082015181840152602081019050610803565b50505050905090810190601f16801561084b5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561086557600080fd5b5061086e61156d565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156108ae578082015181840152602081019050610893565b50505050905090810190601f1680156108db5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610935600480360360408110156108ff57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506115aa565b604051808215151515815260200191505060405180910390f35b34801561095b57600080fd5b506109646115d0565b6040518082815260200191505060405180910390f35b34801561098657600080fd5b506109b36004803603602081101561099d57600080fd5b810190808035906020019092919050505061165d565b604051808215151515815260200191505060405180910390f35b3480156109d957600080fd5b50610a3a600480360360808110156109f057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001909291908035906020019092919050505061167d565b6040518082815260200191505060405180910390f35b348015610a5c57600080fd5b50610a6561169d565b6040518082815260200191505060405180910390f35b348015610a8757600080fd5b50610a906116a2565b6040518082815260200191505060405180910390f35b348015610ab257600080fd5b50610abb6116a8565b6040518082815260200191505060405180910390f35b348015610add57600080fd5b50610b2060048036036020811015610af457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611735565b005b348015610b2e57600080fd5b50610b37611752565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b60606040518060400160405280600b81526020017f4d6174696320546f6b656e000000000000000000000000000000000000000000815250905090565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f44697361626c656420666561747572650000000000000000000000000000000081525060200191505060405180910390fd5b6000601260ff16600a0a6402540be40002905090565b6000808511610c4857600080fd5b6000831480610c575750824311155b610cc9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f5369676e6174757265206973206578706972656400000000000000000000000081525060200191505060405180910390fd5b6000610cd73387878761167d565b9050600015156005600083815260200190815260200160002060009054906101000a900460ff16151514610d73576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600f8152602001807f536967206465616374697661746564000000000000000000000000000000000081525060200191505060405180910390fd5b60016005600083815260200190815260200160002060006101000a81548160ff021916908315150217905550610ded8189898080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061132f565b9150610dfa828488611778565b50509695505050505050565b60003390506000610e1682611238565b9050610e2d83600654611b3590919063ffffffff16565b600681905550600083118015610e4257508234145b610eb4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f496e73756666696369656e7420616d6f756e740000000000000000000000000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff16600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167febff2602b3f468259e1e99f613fed6691f3a6526effe6ef3e768ba7ae7a36c4f8584610f3087611238565b60405180848152602001838152602001828152602001935050505060405180910390a3505050565b60006012905090565b610f696114dd565b610f7257600080fd5b600081118015610faf5750600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b611004576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180611f036023913960400191505060405180910390fd5b600061100f83611238565b905060008390508073ffffffffffffffffffffffffffffffffffffffff166108fc849081150290604051600060405180830381858888f1935050505015801561105c573d6000803e3d6000fd5b5061107283600654611b5590919063ffffffff16565b6006819055508373ffffffffffffffffffffffffffffffffffffffff16600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f4e2ca0515ed1aef1395f66b5303bb5d6f1bf9d61a353fa53f73f8ac9973fa9f685856110f489611238565b60405180848152602001838152602001828152602001935050505060405180910390a350505050565b600760009054906101000a900460ff1615611183576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180611ee06023913960400191505060405180910390fd5b6001600760006101000a81548160ff02191690831515021790555080600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506111e882611b74565b5050565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008173ffffffffffffffffffffffffffffffffffffffff16319050919050565b6112616114dd565b61126a57600080fd5b600073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b60065481565b600080600080604185511461134a57600093505050506114ae565b602085015192506040850151915060ff6041860151169050601b8160ff16101561137557601b810190505b601b8160ff161415801561138d5750601c8160ff1614155b1561139e57600093505050506114ae565b60018682858560405160008152602001604052604051808581526020018460ff1660ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa1580156113fb573d6000803e3d6000fd5b505050602060405103519350600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614156114aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f4572726f7220696e2065637265636f766572000000000000000000000000000081525060200191505060405180910390fd5b5050505b92915050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614905090565b6040518060400160405280600181526020017f890000000000000000000000000000000000000000000000000000000000000081525081565b60606040518060400160405280600581526020017f4d41544943000000000000000000000000000000000000000000000000000000815250905090565b60008134146115bc57600090506115ca565b6115c7338484611778565b90505b92915050565b6040518060800160405280605b8152602001611f78605b91396040516020018082805190602001908083835b6020831061161f57805182526020820191506020810190506020830392506115fc565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012081565b60056020528060005260406000206000915054906101000a900460ff1681565b600061169361168e86868686611c6c565b611d42565b9050949350505050565b608981565b60015481565b604051806080016040528060528152602001611f26605291396040516020018082805190602001908083835b602083106116f757805182526020820191506020810190506020830392506116d4565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012081565b61173d6114dd565b61174657600080fd5b61174f81611b74565b50565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000803073ffffffffffffffffffffffffffffffffffffffff166370a08231866040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b1580156117f857600080fd5b505afa15801561180c573d6000803e3d6000fd5b505050506040513d602081101561182257600080fd5b8101908080519060200190929190505050905060003073ffffffffffffffffffffffffffffffffffffffff166370a08231866040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b1580156118b457600080fd5b505afa1580156118c8573d6000803e3d6000fd5b505050506040513d60208110156118de57600080fd5b810190808051906020019092919050505090506118fc868686611d8c565b8473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fe6497e3ee548a3372136af2fcb0696db31fc6cf20260707645068bd3fe97f3c48786863073ffffffffffffffffffffffffffffffffffffffff166370a082318e6040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015611a0457600080fd5b505afa158015611a18573d6000803e3d6000fd5b505050506040513d6020811015611a2e57600080fd5b81019080805190602001909291905050503073ffffffffffffffffffffffffffffffffffffffff166370a082318e6040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015611abc57600080fd5b505afa158015611ad0573d6000803e3d6000fd5b505050506040513d6020811015611ae657600080fd5b8101908080519060200190929190505050604051808681526020018581526020018481526020018381526020018281526020019550505050505060405180910390a46001925050509392505050565b600082821115611b4457600080fd5b600082840390508091505092915050565b600080828401905083811015611b6a57600080fd5b8091505092915050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611bae57600080fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000806040518060800160405280605b8152602001611f78605b91396040516020018082805190602001908083835b60208310611cbe5780518252602082019150602081019050602083039250611c9b565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120905060405181815273ffffffffffffffffffffffffffffffffffffffff8716602082015285604082015284606082015283608082015260a0812092505081915050949350505050565b60008060015490506040517f190100000000000000000000000000000000000000000000000000000000000081528160028201528360228201526042812092505081915050919050565b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611e2e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f63616e27742073656e6420746f204d524332300000000000000000000000000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015611e74573d6000803e3d6000fd5b508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a350505056fe54686520636f6e747261637420697320616c726561647920696e697469616c697a6564496e73756666696369656e7420616d6f756e74206f7220696e76616c69642075736572454950373132446f6d61696e28737472696e67206e616d652c737472696e672076657273696f6e2c75696e7432353620636861696e49642c6164647265737320766572696679696e67436f6e747261637429546f6b656e5472616e736665724f726465722861646472657373207370656e6465722c75696e7432353620746f6b656e49644f72416d6f756e742c6279746573333220646174612c75696e743235362065787069726174696f6e29a265627a7a7231582098247ec3c8d127ebf969c8f317e340b1cd6c481af077234c38e0c7d92aba4d6364736f6c634300050b0032" + }, + "5973918275C01F50555d44e92c9d9b353CaDAD54": { + "balance": "0x3635c9adc5dea00000" + }, + "b8bB158B93c94ed35c1970D610d1E2B34E26652c": { + "balance": "0x3635c9adc5dea00000" + }, + "F84C74dEa96DF0EC22e11e7C33996C73FCC2D822": { + "balance": "0x3635c9adc5dea00000" + }, + "b702f1C9154ac9c08Da247a8e30ee6F2F3373f41": { + "balance": "0x3635c9adc5dea00000" + }, + "7fCD58C2D53D980b247F1612FdbA93E9a76193E6": { + "balance": "0x3635c9adc5dea00000" + }, + "0375b2fc7140977c9c76D45421564e354ED42277": { + "balance": "0x3635c9adc5dea00000" + }, + "42EEfcda06eaD475cdE3731B8eb138e88CD0bAC3": { + "balance": "0x3635c9adc5dea00000" + } +} diff --git a/command/server/chains/allocs/mumbai.json b/command/server/chains/allocs/mumbai.json new file mode 100644 index 0000000000000000000000000000000000000000..e90415e3193b60f1fa6e7ae915cafb189d2c6788 --- /dev/null +++ b/command/server/chains/allocs/mumbai.json @@ -0,0 +1,30 @@ +{ + "0000000000000000000000000000000000001000": { + "balance": "0x0", + "code": "0x608060405234801561001057600080fd5b50600436106101f05760003560e01c806360c8614d1161010f578063af26aa96116100a2578063d5b844eb11610071578063d5b844eb14610666578063dcf2793a14610684578063e3b7c924146106b6578063f59cf565146106d4576101f0565b8063af26aa96146105c7578063b71d7a69146105e7578063b7ab4db514610617578063c1b3c91914610636576101f0565b806370ba5707116100de57806370ba57071461052b57806398ab2b621461055b5780639d11b80714610579578063ae756451146105a9576101f0565b806360c8614d1461049c57806365b3a1e2146104bc57806366332354146104db578063687a9bd6146104f9576101f0565b80633434735f1161018757806344d6528f1161015657806344d6528f146103ee5780634dbc959f1461041e57806355614fcc1461043c578063582a8d081461046c576101f0565b80633434735f1461035257806335ddfeea1461037057806343ee8213146103a057806344c15cb1146103be576101f0565b806323f2a73f116101c357806323f2a73f146102a45780632bc06564146102d45780632de3a180146102f25780632eddf35214610322576101f0565b8063047a6c5b146101f55780630c35b1cb146102275780631270b5741461025857806323c2a2b414610288575b600080fd5b61020f600480360361020a9190810190612b24565b610706565b60405161021e93929190613463565b60405180910390f35b610241600480360361023c9190810190612b24565b61075d565b60405161024f929190613284565b60405180910390f35b610272600480360361026d9190810190612b4d565b610939565b60405161027f91906132bb565b60405180910390f35b6102a2600480360361029d9190810190612c2c565b610a91565b005b6102be60048036036102b99190810190612b4d565b61112a565b6040516102cb91906132bb565b60405180910390f35b6102dc611281565b6040516102e99190613411565b60405180910390f35b61030c60048036036103079190810190612a81565b611286565b60405161031991906132d6565b60405180910390f35b61033c60048036036103379190810190612b24565b611307565b6040516103499190613411565b60405180910390f35b61035a611437565b6040516103679190613269565b60405180910390f35b61038a60048036036103859190810190612abd565b61144f565b60405161039791906132bb565b60405180910390f35b6103a861151a565b6040516103b591906132d6565b60405180910390f35b6103d860048036036103d39190810190612b89565b611531565b6040516103e59190613411565b60405180910390f35b61040860048036036104039190810190612b4d565b611619565b60405161041591906133f6565b60405180910390f35b610426611781565b6040516104339190613411565b60405180910390f35b61045660048036036104519190810190612a06565b611791565b60405161046391906132bb565b60405180910390f35b61048660048036036104819190810190612a2f565b6117ab565b60405161049391906132d6565b60405180910390f35b6104a4611829565b6040516104b393929190613463565b60405180910390f35b6104c461189d565b6040516104d2929190613284565b60405180910390f35b6104e3611b6e565b6040516104f09190613411565b60405180910390f35b610513600480360361050e9190810190612bf0565b611b73565b6040516105229392919061342c565b60405180910390f35b61054560048036036105409190810190612a06565b611bd7565b60405161055291906132bb565b60405180910390f35b610563611bf1565b60405161057091906132d6565b60405180910390f35b610593600480360361058e9190810190612b24565b611c08565b6040516105a09190613411565b60405180910390f35b6105b1611d39565b6040516105be91906132d6565b60405180910390f35b6105cf611d50565b6040516105de93929190613463565b60405180910390f35b61060160048036036105fc9190810190612b24565b611db1565b60405161060e9190613411565b60405180910390f35b61061f611eb1565b60405161062d929190613284565b60405180910390f35b610650600480360361064b9190810190612b24565b611ec5565b60405161065d9190613411565b60405180910390f35b61066e611ee6565b60405161067b919061349a565b60405180910390f35b61069e60048036036106999190810190612bf0565b611eeb565b6040516106ad9392919061342c565b60405180910390f35b6106be611f4f565b6040516106cb9190613411565b60405180910390f35b6106ee60048036036106e99190810190612b24565b611f61565b6040516106fd93929190613463565b60405180910390f35b60008060006002600085815260200190815260200160002060000154600260008681526020019081526020016000206001015460026000878152602001908152602001600020600201549250925092509193909250565b60608060ff83116107795761077061189d565b91509150610934565b600061078484611db1565b9050606060016000838152602001908152602001600020805490506040519080825280602002602001820160405280156107cd5781602001602082028038833980820191505090505b509050606060016000848152602001908152602001600020805490506040519080825280602002602001820160405280156108175781602001602082028038833980820191505090505b50905060008090505b60016000858152602001908152602001600020805490508110156109295760016000858152602001908152602001600020818154811061085c57fe5b906000526020600020906003020160020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1683828151811061089a57fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250506001600085815260200190815260200160002081815481106108f257fe5b90600052602060002090600302016001015482828151811061091057fe5b6020026020010181815250508080600101915050610820565b508181945094505050505b915091565b6000606060016000858152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b82821015610a0c578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152505081526020019060010190610970565b50505050905060008090505b8151811015610a84578373ffffffffffffffffffffffffffffffffffffffff16828281518110610a4457fe5b60200260200101516040015173ffffffffffffffffffffffffffffffffffffffff161415610a7757600192505050610a8b565b8080600101915050610a18565b5060009150505b92915050565b73fffffffffffffffffffffffffffffffffffffffe73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610b13576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b0a906133d6565b60405180910390fd5b6000610b1d611781565b90506000811415610b3157610b30611f8b565b5b610b456001826122ac90919063ffffffff16565b8814610b86576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b7d90613356565b60405180910390fd5b868611610bc8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bbf906133b6565b60405180910390fd5b6000604060018989030181610bd957fe5b0614610c1a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c1190613396565b60405180910390fd5b8660026000838152602001908152602001600020600101541115610c73576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c6a90613336565b60405180910390fd5b6000600260008a81526020019081526020016000206000015414610ccc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cc390613376565b60405180910390fd5b604051806060016040528089815260200188815260200187815250600260008a8152602001908152602001600020600082015181600001556020820151816001015560408201518160020155905050600388908060018154018082558091505090600182039060005260206000200160009091929091909150555060008060008a815260200190815260200160002081610d669190612800565b506000600160008a815260200190815260200160002081610d879190612800565b506060610ddf610dda87878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506122cb565b6122f9565b905060008090505b8151811015610f51576060610e0e838381518110610e0157fe5b60200260200101516122f9565b90506000808c81526020019081526020016000208054809190600101610e349190612800565b506040518060600160405280610e5d83600081518110610e5057fe5b60200260200101516123d6565b8152602001610e7f83600181518110610e7257fe5b60200260200101516123d6565b8152602001610ea183600281518110610e9457fe5b6020026020010151612447565b73ffffffffffffffffffffffffffffffffffffffff168152506000808d81526020019081526020016000208381548110610ed757fe5b9060005260206000209060030201600082015181600001556020820151816001015560408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550905050508080600101915050610de7565b506060610fa9610fa486868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506122cb565b6122f9565b905060008090505b815181101561111d576060610fd8838381518110610fcb57fe5b60200260200101516122f9565b9050600160008d81526020019081526020016000208054809190600101610fff9190612800565b5060405180606001604052806110288360008151811061101b57fe5b60200260200101516123d6565b815260200161104a8360018151811061103d57fe5b60200260200101516123d6565b815260200161106c8360028151811061105f57fe5b6020026020010151612447565b73ffffffffffffffffffffffffffffffffffffffff16815250600160008e815260200190815260200160002083815481106110a357fe5b9060005260206000209060030201600082015181600001556020820151816001015560408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550905050508080600101915050610fb1565b5050505050505050505050565b60006060600080858152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b828210156111fc578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152505081526020019060010190611160565b50505050905060008090505b8151811015611274578373ffffffffffffffffffffffffffffffffffffffff1682828151811061123457fe5b60200260200101516040015173ffffffffffffffffffffffffffffffffffffffff1614156112675760019250505061127b565b8080600101915050611208565b5060009150505b92915050565b604081565b60006002600160f81b84846040516020016112a3939291906131d6565b6040516020818303038152906040526040516112bf9190613213565b602060405180830381855afa1580156112dc573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052506112ff9190810190612a58565b905092915050565b60006060600080848152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b828210156113d9578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815250508152602001906001019061133d565b505050509050600080905060008090505b825181101561142c5761141d83828151811061140257fe5b602002602001015160200151836122ac90919063ffffffff16565b915080806001019150506113ea565b508092505050919050565b73fffffffffffffffffffffffffffffffffffffffe81565b600080600080859050600060218087518161146657fe5b04029050600081111561147f5761147c876117ab565b91505b6000602190505b818111611509576000600182038801519050818801519550806000602081106114ab57fe5b1a60f81b9450600060f81b857effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614156114f0576114e98685611286565b93506114fd565b6114fa8487611286565b93505b50602181019050611486565b508782149450505050509392505050565b60405161152690613254565b604051809103902081565b60008060009050600080905060008090505b84518167ffffffffffffffff16101561160c57606061156e868367ffffffffffffffff16604161246a565b9050600061158582896124f690919063ffffffff16565b905061158f612832565b6115998a83611619565b90506115a58a8361112a565b80156115dc57508473ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16115b156115fe578194506115fb8160200151876122ac90919063ffffffff16565b95505b505050604181019050611543565b5081925050509392505050565b611621612832565b6060600080858152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b828210156116f1578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152505081526020019060010190611655565b50505050905060008090505b8151811015611779578373ffffffffffffffffffffffffffffffffffffffff1682828151811061172957fe5b60200260200101516040015173ffffffffffffffffffffffffffffffffffffffff16141561176c5781818151811061175d57fe5b60200260200101519250611779565b80806001019150506116fd565b505092915050565b600061178c43611db1565b905090565b60006117a461179e611781565b8361112a565b9050919050565b60006002600060f81b836040516020016117c69291906131aa565b6040516020818303038152906040526040516117e29190613213565b602060405180830381855afa1580156117ff573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052506118229190810190612a58565b9050919050565b60008060008061184a600161183c611781565b6122ac90919063ffffffff16565b905060026000828152602001908152602001600020600001546002600083815260200190815260200160002060010154600260008481526020019081526020016000206002015493509350935050909192565b606080606060056040519080825280602002602001820160405280156118d25781602001602082028038833980820191505090505b50905073c26880a0af2ea0c7e8130e6ec47af756465452e8816000815181106118f757fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505073be188d6641e8b680743a4815dfa0f6208038960f8160018151811061195357fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505073c275dc8be39f50d12f66b6a63629c39da5bae5bd816002815181106119af57fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505073f903ba9e006193c1527bfbe65fe2123704ea3f9981600381518110611a0b57fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505073928ed6a3e94437bbd316ccad78479f1d163a6a8c81600481518110611a6757fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060606005604051908082528060200260200182016040528015611ad35781602001602082028038833980820191505090505b50905061271081600081518110611ae657fe5b60200260200101818152505061271081600181518110611b0257fe5b60200260200101818152505061271081600281518110611b1e57fe5b60200260200101818152505061271081600381518110611b3a57fe5b60200260200101818152505061271081600481518110611b5657fe5b60200260200101818152505081819350935050509091565b60ff81565b60016020528160005260406000208181548110611b8c57fe5b9060005260206000209060030201600091509150508060000154908060010154908060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905083565b6000611bea611be4611781565b83610939565b9050919050565b604051611bfd9061322a565b604051809103902081565b6000606060016000848152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b82821015611cdb578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152505081526020019060010190611c3f565b505050509050600080905060008090505b8251811015611d2e57611d1f838281518110611d0457fe5b602002602001015160200151836122ac90919063ffffffff16565b91508080600101915050611cec565b508092505050919050565b604051611d459061323f565b604051809103902081565b600080600080611d5e611781565b905060026000828152602001908152602001600020600001546002600083815260200190815260200160002060010154600260008481526020019081526020016000206002015493509350935050909192565b60008060038054905090505b6000811115611e7157611dce612869565b6002600060036001850381548110611de257fe5b906000526020600020015481526020019081526020016000206040518060600160405290816000820154815260200160018201548152602001600282015481525050905083816020015111158015611e3f57506000816040015114155b8015611e4f575080604001518411155b15611e6257806000015192505050611eac565b50808060019003915050611dbd565b5060006003805490501115611ea757600360016003805490500381548110611e9557fe5b90600052602060002001549050611eac565b600090505b919050565b606080611ebd4361075d565b915091509091565b60038181548110611ed257fe5b906000526020600020016000915090505481565b600281565b60006020528160005260406000208181548110611f0457fe5b9060005260206000209060030201600091509150508060000154908060010154908060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905083565b600060404381611f5b57fe5b04905090565b60026020528060005260406000206000915090508060000154908060010154908060020154905083565b606080611f9661189d565b8092508193505050600080905060405180606001604052808281526020016000815260200160ff81525060026000838152602001908152602001600020600082015181600001556020820151816001015560408201518160020155905050600381908060018154018082558091505090600182039060005260206000200160009091929091909150555060008060008381526020019081526020016000208161203f9190612800565b50600060016000838152602001908152602001600020816120609190612800565b5060008090505b83518110156121825760008083815260200190815260200160002080548091906001016120949190612800565b5060405180606001604052808281526020018483815181106120b257fe5b602002602001015181526020018583815181106120cb57fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff16815250600080848152602001908152602001600020828154811061210957fe5b9060005260206000209060030201600082015181600001556020820151816001015560408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055509050508080600101915050612067565b5060008090505b83518110156122a6576001600083815260200190815260200160002080548091906001016121b79190612800565b5060405180606001604052808281526020018483815181106121d557fe5b602002602001015181526020018583815181106121ee57fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681525060016000848152602001908152602001600020828154811061222d57fe5b9060005260206000209060030201600082015181600001556020820151816001015560408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055509050508080600101915050612189565b50505050565b6000808284019050838110156122c157600080fd5b8091505092915050565b6122d361288a565b600060208301905060405180604001604052808451815260200182815250915050919050565b606061230482612600565b61230d57600080fd5b60006123188361264e565b905060608160405190808252806020026020018201604052801561235657816020015b6123436128a4565b81526020019060019003908161233b5790505b509050600061236885602001516126bf565b8560200151019050600080600090505b848110156123c95761238983612748565b91506040518060400160405280838152602001848152508482815181106123ac57fe5b602002602001018190525081830192508080600101915050612378565b5082945050505050919050565b60008082600001511180156123f057506021826000015111155b6123f957600080fd5b600061240883602001516126bf565b9050600081846000015103905060008083866020015101905080519150602083101561243b57826020036101000a820491505b81945050505050919050565b6000601582600001511461245a57600080fd5b612463826123d6565b9050919050565b60608183018451101561247c57600080fd5b6060821560008114612499576040519150602082016040526124ea565b6040519150601f8416801560200281840101858101878315602002848b0101015b818310156124d757805183526020830192506020810190506124ba565b50868552601f19601f8301166040525050505b50809150509392505050565b600080600080604185511461251157600093505050506125fa565b602085015192506040850151915060ff6041860151169050601b8160ff16101561253c57601b810190505b601b8160ff16141580156125545750601c8160ff1614155b1561256557600093505050506125fa565b60006001878386866040516000815260200160405260405161258a94939291906132f1565b6020604051602081039080840390855afa1580156125ac573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156125f257600080fd5b809450505050505b92915050565b600080826000015114156126175760009050612649565b60008083602001519050805160001a915060c060ff168260ff16101561264257600092505050612649565b6001925050505b919050565b6000808260000151141561266557600090506126ba565b6000809050600061267984602001516126bf565b84602001510190506000846000015185602001510190505b808210156126b3576126a282612748565b820191508280600101935050612691565b8293505050505b919050565b600080825160001a9050608060ff168110156126df576000915050612743565b60b860ff16811080612704575060c060ff168110158015612703575060f860ff1681105b5b15612713576001915050612743565b60c060ff168110156127335760018060b80360ff16820301915050612743565b60018060f80360ff168203019150505b919050565b6000806000835160001a9050608060ff1681101561276957600191506127f6565b60b860ff16811015612786576001608060ff1682030191506127f5565b60c060ff168110156127b65760b78103600185019450806020036101000a855104600182018101935050506127f4565b60f860ff168110156127d357600160c060ff1682030191506127f3565b60f78103600185019450806020036101000a855104600182018101935050505b5b5b5b8192505050919050565b81548183558181111561282d5760030281600302836000526020600020918201910161282c91906128be565b5b505050565b60405180606001604052806000815260200160008152602001600073ffffffffffffffffffffffffffffffffffffffff1681525090565b60405180606001604052806000815260200160008152602001600081525090565b604051806040016040528060008152602001600081525090565b604051806040016040528060008152602001600081525090565b61291191905b8082111561290d5760008082016000905560018201600090556002820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055506003016128c4565b5090565b90565b60008135905061292381613693565b92915050565b600081359050612938816136aa565b92915050565b60008151905061294d816136aa565b92915050565b60008083601f84011261296557600080fd5b8235905067ffffffffffffffff81111561297e57600080fd5b60208301915083600182028301111561299657600080fd5b9250929050565b600082601f8301126129ae57600080fd5b81356129c16129bc826134e2565b6134b5565b915080825260208301602083018583830111156129dd57600080fd5b6129e883828461363d565b50505092915050565b600081359050612a00816136c1565b92915050565b600060208284031215612a1857600080fd5b6000612a2684828501612914565b91505092915050565b600060208284031215612a4157600080fd5b6000612a4f84828501612929565b91505092915050565b600060208284031215612a6a57600080fd5b6000612a788482850161293e565b91505092915050565b60008060408385031215612a9457600080fd5b6000612aa285828601612929565b9250506020612ab385828601612929565b9150509250929050565b600080600060608486031215612ad257600080fd5b6000612ae086828701612929565b9350506020612af186828701612929565b925050604084013567ffffffffffffffff811115612b0e57600080fd5b612b1a8682870161299d565b9150509250925092565b600060208284031215612b3657600080fd5b6000612b44848285016129f1565b91505092915050565b60008060408385031215612b6057600080fd5b6000612b6e858286016129f1565b9250506020612b7f85828601612914565b9150509250929050565b600080600060608486031215612b9e57600080fd5b6000612bac868287016129f1565b9350506020612bbd86828701612929565b925050604084013567ffffffffffffffff811115612bda57600080fd5b612be68682870161299d565b9150509250925092565b60008060408385031215612c0357600080fd5b6000612c11858286016129f1565b9250506020612c22858286016129f1565b9150509250929050565b600080600080600080600060a0888a031215612c4757600080fd5b6000612c558a828b016129f1565b9750506020612c668a828b016129f1565b9650506040612c778a828b016129f1565b955050606088013567ffffffffffffffff811115612c9457600080fd5b612ca08a828b01612953565b9450945050608088013567ffffffffffffffff811115612cbf57600080fd5b612ccb8a828b01612953565b925092505092959891949750929550565b6000612ce88383612d0c565b60208301905092915050565b6000612d00838361317d565b60208301905092915050565b612d15816135b2565b82525050565b612d24816135b2565b82525050565b6000612d358261352e565b612d3f8185613569565b9350612d4a8361350e565b8060005b83811015612d7b578151612d628882612cdc565b9750612d6d8361354f565b925050600181019050612d4e565b5085935050505092915050565b6000612d9382613539565b612d9d818561357a565b9350612da88361351e565b8060005b83811015612dd9578151612dc08882612cf4565b9750612dcb8361355c565b925050600181019050612dac565b5085935050505092915050565b612def816135c4565b82525050565b612e06612e01826135d0565b61367f565b82525050565b612e15816135fc565b82525050565b612e2c612e27826135fc565b613689565b82525050565b6000612e3d82613544565b612e47818561358b565b9350612e5781856020860161364c565b80840191505092915050565b6000612e706004836135a7565b91507f766f7465000000000000000000000000000000000000000000000000000000006000830152600482019050919050565b6000612eb0602d83613596565b91507f537461727420626c6f636b206d7573742062652067726561746572207468616e60008301527f2063757272656e74207370616e000000000000000000000000000000000000006020830152604082019050919050565b6000612f16600f83613596565b91507f496e76616c6964207370616e20696400000000000000000000000000000000006000830152602082019050919050565b6000612f56601383613596565b91507f5370616e20616c726561647920657869737473000000000000000000000000006000830152602082019050919050565b6000612f96604583613596565b91507f446966666572656e6365206265747765656e20737461727420616e6420656e6460008301527f20626c6f636b206d75737420626520696e206d756c7469706c6573206f66207360208301527f7072696e740000000000000000000000000000000000000000000000000000006040830152606082019050919050565b6000613022602a83613596565b91507f456e6420626c6f636b206d7573742062652067726561746572207468616e207360008301527f7461727420626c6f636b000000000000000000000000000000000000000000006020830152604082019050919050565b6000613088601283613596565b91507f4e6f742053797374656d204164646573732100000000000000000000000000006000830152602082019050919050565b60006130c86005836135a7565b91507f38303030310000000000000000000000000000000000000000000000000000006000830152600582019050919050565b6000613108600e836135a7565b91507f6865696d64616c6c2d38303030310000000000000000000000000000000000006000830152600e82019050919050565b606082016000820151613151600085018261317d565b506020820151613164602085018261317d565b5060408201516131776040850182612d0c565b50505050565b61318681613626565b82525050565b61319581613626565b82525050565b6131a481613630565b82525050565b60006131b68285612df5565b6001820191506131c68284612e1b565b6020820191508190509392505050565b60006131e28286612df5565b6001820191506131f28285612e1b565b6020820191506132028284612e1b565b602082019150819050949350505050565b600061321f8284612e32565b915081905092915050565b600061323582612e63565b9150819050919050565b600061324a826130bb565b9150819050919050565b600061325f826130fb565b9150819050919050565b600060208201905061327e6000830184612d1b565b92915050565b6000604082019050818103600083015261329e8185612d2a565b905081810360208301526132b28184612d88565b90509392505050565b60006020820190506132d06000830184612de6565b92915050565b60006020820190506132eb6000830184612e0c565b92915050565b60006080820190506133066000830187612e0c565b613313602083018661319b565b6133206040830185612e0c565b61332d6060830184612e0c565b95945050505050565b6000602082019050818103600083015261334f81612ea3565b9050919050565b6000602082019050818103600083015261336f81612f09565b9050919050565b6000602082019050818103600083015261338f81612f49565b9050919050565b600060208201905081810360008301526133af81612f89565b9050919050565b600060208201905081810360008301526133cf81613015565b9050919050565b600060208201905081810360008301526133ef8161307b565b9050919050565b600060608201905061340b600083018461313b565b92915050565b6000602082019050613426600083018461318c565b92915050565b6000606082019050613441600083018661318c565b61344e602083018561318c565b61345b6040830184612d1b565b949350505050565b6000606082019050613478600083018661318c565b613485602083018561318c565b613492604083018461318c565b949350505050565b60006020820190506134af600083018461319b565b92915050565b6000604051905081810181811067ffffffffffffffff821117156134d857600080fd5b8060405250919050565b600067ffffffffffffffff8211156134f957600080fd5b601f19601f8301169050602081019050919050565b6000819050602082019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b60006135bd82613606565b9050919050565b60008115159050919050565b60007fff0000000000000000000000000000000000000000000000000000000000000082169050919050565b6000819050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b82818337600083830152505050565b60005b8381101561366a57808201518184015260208101905061364f565b83811115613679576000848401525b50505050565b6000819050919050565b6000819050919050565b61369c816135b2565b81146136a757600080fd5b50565b6136b3816135fc565b81146136be57600080fd5b50565b6136ca81613626565b81146136d557600080fd5b5056fea365627a7a723158208f52ee07630ffe523cc6ad3e15f437f973dcfa36729cd697f9b0fc4a145a48f06c6578706572696d656e74616cf564736f6c634300050b0040" + }, + "0000000000000000000000000000000000001001": { + "balance": "0x0", + "code": "0x608060405234801561001057600080fd5b50600436106100415760003560e01c806319494a17146100465780633434735f146100e15780635407ca671461012b575b600080fd5b6100c76004803603604081101561005c57600080fd5b81019080803590602001909291908035906020019064010000000081111561008357600080fd5b82018360208201111561009557600080fd5b803590602001918460018302840111640100000000831117156100b757600080fd5b9091929391929390505050610149565b604051808215151515815260200191505060405180910390f35b6100e961047a565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610133610492565b6040518082815260200191505060405180910390f35b600073fffffffffffffffffffffffffffffffffffffffe73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610200576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f4e6f742053797374656d2041646465737321000000000000000000000000000081525060200191505060405180910390fd5b606061025761025285858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610498565b6104c6565b905060006102788260008151811061026b57fe5b60200260200101516105a3565b905080600160005401146102f4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f537461746549647320617265206e6f742073657175656e7469616c000000000081525060200191505060405180910390fd5b600080815480929190600101919050555060006103248360018151811061031757fe5b6020026020010151610614565b905060606103458460028151811061033857fe5b6020026020010151610637565b9050610350826106c3565b1561046f576000624c4b409050606084836040516024018083815260200180602001828103825283818151815260200191508051906020019080838360005b838110156103aa57808201518184015260208101905061038f565b50505050905090810190601f1680156103d75780820380516001836020036101000a031916815260200191505b5093505050506040516020818303038152906040527f26c53bea000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050905060008082516020840160008887f1965050505b505050509392505050565b73fffffffffffffffffffffffffffffffffffffffe81565b60005481565b6104a0610943565b600060208301905060405180604001604052808451815260200182815250915050919050565b60606104d1826106dc565b6104da57600080fd5b60006104e58361072a565b905060608160405190808252806020026020018201604052801561052357816020015b61051061095d565b8152602001906001900390816105085790505b5090506000610535856020015161079b565b8560200151019050600080600090505b848110156105965761055683610824565b915060405180604001604052808381526020018481525084828151811061057957fe5b602002602001018190525081830192508080600101915050610545565b5082945050505050919050565b60008082600001511180156105bd57506021826000015111155b6105c657600080fd5b60006105d5836020015161079b565b9050600081846000015103905060008083866020015101905080519150602083101561060857826020036101000a820491505b81945050505050919050565b6000601582600001511461062757600080fd5b610630826105a3565b9050919050565b6060600082600001511161064a57600080fd5b6000610659836020015161079b565b905060008184600001510390506060816040519080825280601f01601f19166020018201604052801561069b5781602001600182028038833980820191505090505b50905060008160200190506106b78487602001510182856108dc565b81945050505050919050565b600080823b905060008163ffffffff1611915050919050565b600080826000015114156106f35760009050610725565b60008083602001519050805160001a915060c060ff168260ff16101561071e57600092505050610725565b6001925050505b919050565b600080826000015114156107415760009050610796565b60008090506000610755846020015161079b565b84602001510190506000846000015185602001510190505b8082101561078f5761077e82610824565b82019150828060010193505061076d565b8293505050505b919050565b600080825160001a9050608060ff168110156107bb57600091505061081f565b60b860ff168110806107e0575060c060ff1681101580156107df575060f860ff1681105b5b156107ef57600191505061081f565b60c060ff1681101561080f5760018060b80360ff1682030191505061081f565b60018060f80360ff168203019150505b919050565b6000806000835160001a9050608060ff1681101561084557600191506108d2565b60b860ff16811015610862576001608060ff1682030191506108d1565b60c060ff168110156108925760b78103600185019450806020036101000a855104600182018101935050506108d0565b60f860ff168110156108af57600160c060ff1682030191506108cf565b60f78103600185019450806020036101000a855104600182018101935050505b5b5b5b8192505050919050565b60008114156108ea5761093e565b5b602060ff16811061091a5782518252602060ff1683019250602060ff1682019150602060ff16810390506108eb565b6000600182602060ff16036101000a03905080198451168184511681811785525050505b505050565b604051806040016040528060008152602001600081525090565b60405180604001604052806000815260200160008152509056fea265627a7a7231582083fbdacb76f32b4112d0f7db9a596937925824798a0026ba0232322390b5263764736f6c634300050b0032" + }, + "0000000000000000000000000000000000001010": { + "balance": "0x204fcd4f31349d83b6e00000", + "code": "0x60806040526004361061019c5760003560e01c806377d32e94116100ec578063acd06cb31161008a578063e306f77911610064578063e306f77914610a7b578063e614d0d614610aa6578063f2fde38b14610ad1578063fc0c546a14610b225761019c565b8063acd06cb31461097a578063b789543c146109cd578063cc79f97b14610a505761019c565b80639025e64c116100c65780639025e64c146107c957806395d89b4114610859578063a9059cbb146108e9578063abceeba21461094f5761019c565b806377d32e94146106315780638da5cb5b146107435780638f32d59b1461079a5761019c565b806347e7ef24116101595780637019d41a116101335780637019d41a1461053357806370a082311461058a578063715018a6146105ef578063771282f6146106065761019c565b806347e7ef2414610410578063485cc9551461046b57806360f96a8f146104dc5761019c565b806306fdde03146101a15780631499c5921461023157806318160ddd1461028257806319d27d9c146102ad5780632e1a7d4d146103b1578063313ce567146103df575b600080fd5b3480156101ad57600080fd5b506101b6610b79565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101f65780820151818401526020810190506101db565b50505050905090810190601f1680156102235780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561023d57600080fd5b506102806004803603602081101561025457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610bb6565b005b34801561028e57600080fd5b50610297610c24565b6040518082815260200191505060405180910390f35b3480156102b957600080fd5b5061036f600480360360a08110156102d057600080fd5b81019080803590602001906401000000008111156102ed57600080fd5b8201836020820111156102ff57600080fd5b8035906020019184600183028401116401000000008311171561032157600080fd5b9091929391929390803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610c3a565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6103dd600480360360208110156103c757600080fd5b8101908080359060200190929190505050610e06565b005b3480156103eb57600080fd5b506103f4610f58565b604051808260ff1660ff16815260200191505060405180910390f35b34801561041c57600080fd5b506104696004803603604081101561043357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610f61565b005b34801561047757600080fd5b506104da6004803603604081101561048e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061111d565b005b3480156104e857600080fd5b506104f16111ec565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561053f57600080fd5b50610548611212565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561059657600080fd5b506105d9600480360360208110156105ad57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611238565b6040518082815260200191505060405180910390f35b3480156105fb57600080fd5b50610604611259565b005b34801561061257600080fd5b5061061b611329565b6040518082815260200191505060405180910390f35b34801561063d57600080fd5b506107016004803603604081101561065457600080fd5b81019080803590602001909291908035906020019064010000000081111561067b57600080fd5b82018360208201111561068d57600080fd5b803590602001918460018302840111640100000000831117156106af57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929050505061132f565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561074f57600080fd5b506107586114b4565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156107a657600080fd5b506107af6114dd565b604051808215151515815260200191505060405180910390f35b3480156107d557600080fd5b506107de611534565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561081e578082015181840152602081019050610803565b50505050905090810190601f16801561084b5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561086557600080fd5b5061086e61156d565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156108ae578082015181840152602081019050610893565b50505050905090810190601f1680156108db5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610935600480360360408110156108ff57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506115aa565b604051808215151515815260200191505060405180910390f35b34801561095b57600080fd5b506109646115d0565b6040518082815260200191505060405180910390f35b34801561098657600080fd5b506109b36004803603602081101561099d57600080fd5b810190808035906020019092919050505061165d565b604051808215151515815260200191505060405180910390f35b3480156109d957600080fd5b50610a3a600480360360808110156109f057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001909291908035906020019092919050505061167d565b6040518082815260200191505060405180910390f35b348015610a5c57600080fd5b50610a6561169d565b6040518082815260200191505060405180910390f35b348015610a8757600080fd5b50610a906116a4565b6040518082815260200191505060405180910390f35b348015610ab257600080fd5b50610abb6116aa565b6040518082815260200191505060405180910390f35b348015610add57600080fd5b50610b2060048036036020811015610af457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611737565b005b348015610b2e57600080fd5b50610b37611754565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b60606040518060400160405280600b81526020017f4d6174696320546f6b656e000000000000000000000000000000000000000000815250905090565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f44697361626c656420666561747572650000000000000000000000000000000081525060200191505060405180910390fd5b6000601260ff16600a0a6402540be40002905090565b6000808511610c4857600080fd5b6000831480610c575750824311155b610cc9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f5369676e6174757265206973206578706972656400000000000000000000000081525060200191505060405180910390fd5b6000610cd73387878761167d565b9050600015156005600083815260200190815260200160002060009054906101000a900460ff16151514610d73576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600f8152602001807f536967206465616374697661746564000000000000000000000000000000000081525060200191505060405180910390fd5b60016005600083815260200190815260200160002060006101000a81548160ff021916908315150217905550610ded8189898080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061132f565b9150610dfa82848861177a565b50509695505050505050565b60003390506000610e1682611238565b9050610e2d83600654611b3790919063ffffffff16565b600681905550600083118015610e4257508234145b610eb4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f496e73756666696369656e7420616d6f756e740000000000000000000000000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff16600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167febff2602b3f468259e1e99f613fed6691f3a6526effe6ef3e768ba7ae7a36c4f8584610f3087611238565b60405180848152602001838152602001828152602001935050505060405180910390a3505050565b60006012905090565b610f696114dd565b610f7257600080fd5b600081118015610faf5750600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b611004576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180611e636023913960400191505060405180910390fd5b600061100f83611238565b905060008390508073ffffffffffffffffffffffffffffffffffffffff166108fc849081150290604051600060405180830381858888f1935050505015801561105c573d6000803e3d6000fd5b5061107283600654611b5790919063ffffffff16565b6006819055508373ffffffffffffffffffffffffffffffffffffffff16600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f4e2ca0515ed1aef1395f66b5303bb5d6f1bf9d61a353fa53f73f8ac9973fa9f685856110f489611238565b60405180848152602001838152602001828152602001935050505060405180910390a350505050565b600760009054906101000a900460ff1615611183576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180611e406023913960400191505060405180910390fd5b6001600760006101000a81548160ff02191690831515021790555080600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506111e882611b76565b5050565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008173ffffffffffffffffffffffffffffffffffffffff16319050919050565b6112616114dd565b61126a57600080fd5b600073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b60065481565b600080600080604185511461134a57600093505050506114ae565b602085015192506040850151915060ff6041860151169050601b8160ff16101561137557601b810190505b601b8160ff161415801561138d5750601c8160ff1614155b1561139e57600093505050506114ae565b60018682858560405160008152602001604052604051808581526020018460ff1660ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa1580156113fb573d6000803e3d6000fd5b505050602060405103519350600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614156114aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f4572726f7220696e2065637265636f766572000000000000000000000000000081525060200191505060405180910390fd5b5050505b92915050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614905090565b6040518060400160405280600381526020017f013881000000000000000000000000000000000000000000000000000000000081525081565b60606040518060400160405280600581526020017f4d41544943000000000000000000000000000000000000000000000000000000815250905090565b60008134146115bc57600090506115ca565b6115c733848461177a565b90505b92915050565b6040518060800160405280605b8152602001611ed8605b91396040516020018082805190602001908083835b6020831061161f57805182526020820191506020810190506020830392506115fc565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012081565b60056020528060005260406000206000915054906101000a900460ff1681565b600061169361168e86868686611c6e565b611d44565b9050949350505050565b6201388181565b60015481565b604051806080016040528060528152602001611e86605291396040516020018082805190602001908083835b602083106116f957805182526020820191506020810190506020830392506116d6565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012081565b61173f6114dd565b61174857600080fd5b61175181611b76565b50565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000803073ffffffffffffffffffffffffffffffffffffffff166370a08231866040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b1580156117fa57600080fd5b505afa15801561180e573d6000803e3d6000fd5b505050506040513d602081101561182457600080fd5b8101908080519060200190929190505050905060003073ffffffffffffffffffffffffffffffffffffffff166370a08231866040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b1580156118b657600080fd5b505afa1580156118ca573d6000803e3d6000fd5b505050506040513d60208110156118e057600080fd5b810190808051906020019092919050505090506118fe868686611d8e565b8473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fe6497e3ee548a3372136af2fcb0696db31fc6cf20260707645068bd3fe97f3c48786863073ffffffffffffffffffffffffffffffffffffffff166370a082318e6040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015611a0657600080fd5b505afa158015611a1a573d6000803e3d6000fd5b505050506040513d6020811015611a3057600080fd5b81019080805190602001909291905050503073ffffffffffffffffffffffffffffffffffffffff166370a082318e6040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015611abe57600080fd5b505afa158015611ad2573d6000803e3d6000fd5b505050506040513d6020811015611ae857600080fd5b8101908080519060200190929190505050604051808681526020018581526020018481526020018381526020018281526020019550505050505060405180910390a46001925050509392505050565b600082821115611b4657600080fd5b600082840390508091505092915050565b600080828401905083811015611b6c57600080fd5b8091505092915050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611bb057600080fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000806040518060800160405280605b8152602001611ed8605b91396040516020018082805190602001908083835b60208310611cc05780518252602082019150602081019050602083039250611c9d565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120905060405181815273ffffffffffffffffffffffffffffffffffffffff8716602082015285604082015284606082015283608082015260a0812092505081915050949350505050565b60008060015490506040517f190100000000000000000000000000000000000000000000000000000000000081528160028201528360228201526042812092505081915050919050565b8173ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015611dd4573d6000803e3d6000fd5b508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a350505056fe54686520636f6e747261637420697320616c726561647920696e697469616c697a6564496e73756666696369656e7420616d6f756e74206f7220696e76616c69642075736572454950373132446f6d61696e28737472696e67206e616d652c737472696e672076657273696f6e2c75696e7432353620636861696e49642c6164647265737320766572696679696e67436f6e747261637429546f6b656e5472616e736665724f726465722861646472657373207370656e6465722c75696e7432353620746f6b656e49644f72416d6f756e742c6279746573333220646174612c75696e743235362065787069726174696f6e29a265627a7a723158208f81700133738d766ae3d68af591ad588b0125bd91449192179f460893f79f6b64736f6c634300050b0032" + }, + "C26880A0AF2EA0c7E8130e6EC47Af756465452E8": { + "balance": "0x3635c9adc5dea00000" + }, + "be188D6641E8b680743A4815dFA0f6208038960F": { + "balance": "0x3635c9adc5dea00000" + }, + "c275DC8bE39f50D12F66B6a63629C39dA5BAe5bd": { + "balance": "0x3635c9adc5dea00000" + }, + "F903ba9E006193c1527BfBe65fe2123704EA3F99": { + "balance": "0x3635c9adc5dea00000" + }, + "928Ed6A3e94437bbd316cCAD78479f1d163A6A8C": { + "balance": "0x3635c9adc5dea00000" + } + } + \ No newline at end of file diff --git a/command/server/chains/chain.go b/command/server/chains/chain.go new file mode 100644 index 0000000000000000000000000000000000000000..05c12ef0b076d5a349fc4dcf0d9316aa7c897307 --- /dev/null +++ b/command/server/chains/chain.go @@ -0,0 +1,24 @@ +package chains + +import ( + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core" +) + +type Chain struct { + Hash common.Hash + Genesis *core.Genesis + Bootnodes []string + NetworkId uint64 + DNS []string +} + +var chains = map[string]*Chain{ + "mainnet": mainnetBor, + "mumbai": mumbaiTestnet, +} + +func GetChain(name string) (*Chain, bool) { + chain, ok := chains[name] + return chain, ok +} diff --git a/command/server/chains/mainnet.go b/command/server/chains/mainnet.go new file mode 100644 index 0000000000000000000000000000000000000000..ac074ed8cb0407635be6543556aac07ff0639e35 --- /dev/null +++ b/command/server/chains/mainnet.go @@ -0,0 +1,62 @@ +package chains + +import ( + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/params" +) + +var mainnetBor = &Chain{ + Hash: common.HexToHash("0xa9c28ce2141b56c474f1dc504bee9b01eb1bd7d1a507580d5519d4437a97de1b"), + NetworkId: 137, + Genesis: &core.Genesis{ + Config: ¶ms.ChainConfig{ + ChainID: big.NewInt(137), + HomesteadBlock: big.NewInt(0), + DAOForkBlock: nil, + DAOForkSupport: true, + EIP150Hash: common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000"), + EIP150Block: big.NewInt(0), + EIP155Block: big.NewInt(0), + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + IstanbulBlock: big.NewInt(3395000), + MuirGlacierBlock: big.NewInt(3395000), + BerlinBlock: big.NewInt(14750000), + Bor: ¶ms.BorConfig{ + Period: 2, + ProducerDelay: 6, + Sprint: 64, + BackupMultiplier: 2, + ValidatorContract: "0x0000000000000000000000000000000000001000", + StateReceiverContract: "0x0000000000000000000000000000000000001001", + OverrideStateSyncRecords: map[string]int{ + "14949120": 8, + "14949184": 0, + "14953472": 0, + "14953536": 5, + "14953600": 0, + "14953664": 0, + "14953728": 0, + "14953792": 0, + "14953856": 0, + }, + }, + }, + Nonce: 0, + Timestamp: 1590824836, + GasLimit: 10000000, + Difficulty: big.NewInt(1), + Mixhash: common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000"), + Coinbase: common.HexToAddress("0x0000000000000000000000000000000000000000"), + Alloc: readPrealloc("allocs/mainnet.json"), + }, + Bootnodes: []string{ + "enode://0cb82b395094ee4a2915e9714894627de9ed8498fb881cec6db7c65e8b9a5bd7f2f25cc84e71e89d0947e51c76e85d0847de848c7782b13c0255247a6758178c@44.232.55.71:30303", + "enode://88116f4295f5a31538ae409e4d44ad40d22e44ee9342869e7d68bdec55b0f83c1530355ce8b41fbec0928a7d75a5745d528450d30aec92066ab6ba1ee351d710@159.203.9.164:30303", + }, +} diff --git a/command/server/chains/mumbai.go b/command/server/chains/mumbai.go new file mode 100644 index 0000000000000000000000000000000000000000..1003380d104fa8a90a49e62e07fff2c75e0f745e --- /dev/null +++ b/command/server/chains/mumbai.go @@ -0,0 +1,51 @@ +package chains + +import ( + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/params" +) + +var mumbaiTestnet = &Chain{ + Hash: common.HexToHash("0x7b66506a9ebdbf30d32b43c5f15a3b1216269a1ec3a75aa3182b86176a2b1ca7"), + NetworkId: 80001, + Genesis: &core.Genesis{ + Config: ¶ms.ChainConfig{ + ChainID: big.NewInt(80001), + HomesteadBlock: big.NewInt(0), + DAOForkBlock: nil, + DAOForkSupport: true, + EIP150Hash: common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000"), + EIP150Block: big.NewInt(0), + EIP155Block: big.NewInt(0), + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + IstanbulBlock: big.NewInt(2722000), + MuirGlacierBlock: big.NewInt(2722000), + BerlinBlock: big.NewInt(13996000), + Bor: ¶ms.BorConfig{ + Period: 2, + ProducerDelay: 6, + Sprint: 64, + BackupMultiplier: 2, + ValidatorContract: "0x0000000000000000000000000000000000001000", + StateReceiverContract: "0x0000000000000000000000000000000000001001", + }, + }, + Nonce: 0, + Timestamp: 1558348305, + GasLimit: 10000000, + Difficulty: big.NewInt(1), + Mixhash: common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000"), + Coinbase: common.HexToAddress("0x0000000000000000000000000000000000000000"), + Alloc: readPrealloc("allocs/mumbai.json"), + }, + Bootnodes: []string{ + "enode://320553cda00dfc003f499a3ce9598029f364fbb3ed1222fdc20a94d97dcc4d8ba0cd0bfa996579dcc6d17a534741fb0a5da303a90579431259150de66b597251@54.147.31.250:30303", + "enode://f0f48a8781629f95ff02606081e6e43e4aebd503f3d07fc931fad7dd5ca1ba52bd849a6f6c3be0e375cf13c9ae04d859c4a9ae3546dc8ed4f10aa5dbb47d4998@34.226.134.117:30303", + }, +} diff --git a/command/server/chains/utils.go b/command/server/chains/utils.go new file mode 100644 index 0000000000000000000000000000000000000000..5f2f761ea485802f57305767cd033dc19efa0bb1 --- /dev/null +++ b/command/server/chains/utils.go @@ -0,0 +1,27 @@ +package chains + +import ( + "embed" + "encoding/json" + "fmt" + + "github.com/ethereum/go-ethereum/core" +) + +//go:embed allocs +var allocs embed.FS + +func readPrealloc(filename string) core.GenesisAlloc { + f, err := allocs.Open(filename) + if err != nil { + panic(fmt.Sprintf("Could not open genesis preallocation for %s: %v", filename, err)) + } + defer f.Close() + decoder := json.NewDecoder(f) + ga := make(core.GenesisAlloc) + err = decoder.Decode(&ga) + if err != nil { + panic(fmt.Sprintf("Could not parse genesis preallocation for %s: %v", filename, err)) + } + return ga +} diff --git a/command/server/command.go b/command/server/command.go new file mode 100644 index 0000000000000000000000000000000000000000..4b2374dc427480ba2e2b8efaa9319c41ce53c109 --- /dev/null +++ b/command/server/command.go @@ -0,0 +1,102 @@ +package server + +import ( + "fmt" + "os" + "os/signal" + "syscall" + + "github.com/ethereum/go-ethereum/log" + "github.com/mitchellh/cli" +) + +// Command is the command to start the sever +type Command struct { + UI cli.Ui + + // cli configuration + cliConfig *Config + + // final configuration + config *Config + + configFile []string + + srv *Server +} + +// Help implements the cli.Command interface +func (c *Command) Help() string { + return `Usage: bor [options] + + Run the Bor server. + ` + c.Flags().Help() +} + +// Synopsis implements the cli.Command interface +func (c *Command) Synopsis() string { + return "Run the Bor server" +} + +// Run implements the cli.Command interface +func (c *Command) Run(args []string) int { + flags := c.Flags() + if err := flags.Parse(args); err != nil { + c.UI.Error(err.Error()) + return 1 + } + + // read config file + config := DefaultConfig() + for _, configFile := range c.configFile { + cfg, err := readConfigFile(configFile) + if err != nil { + c.UI.Error(err.Error()) + return 1 + } + if err := config.Merge(cfg); err != nil { + c.UI.Error(err.Error()) + return 1 + } + } + if err := config.Merge(c.cliConfig); err != nil { + c.UI.Error(err.Error()) + return 1 + } + c.config = config + + srv, err := NewServer(config) + if err != nil { + c.UI.Error(err.Error()) + return 1 + } + c.srv = srv + + return c.handleSignals() +} + +func (c *Command) handleSignals() int { + signalCh := make(chan os.Signal, 4) + signal.Notify(signalCh, os.Interrupt, syscall.SIGTERM, syscall.SIGHUP) + + sig := <-signalCh + + c.UI.Output(fmt.Sprintf("Caught signal: %v", sig)) + c.UI.Output("Gracefully shutting down agent...") + + gracefulCh := make(chan struct{}) + go func() { + c.srv.Stop() + close(gracefulCh) + }() + + for i := 10; i > 0; i-- { + select { + case <-signalCh: + log.Warn("Already shutting down, interrupt more force stop.", "times", i-1) + case <-gracefulCh: + return 0 + } + } + return 1 +} diff --git a/command/server/config.go b/command/server/config.go new file mode 100644 index 0000000000000000000000000000000000000000..c9ffff481d1bd66ae2167cb7acd407967b393938 --- /dev/null +++ b/command/server/config.go @@ -0,0 +1,899 @@ +package server + +import ( + "fmt" + "io/ioutil" + "math" + "math/big" + "os" + "path/filepath" + "runtime" + "strconv" + "strings" + "time" + + godebug "runtime/debug" + + "github.com/ethereum/go-ethereum/command/server/chains" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/fdlimit" + "github.com/ethereum/go-ethereum/eth/downloader" + "github.com/ethereum/go-ethereum/eth/ethconfig" + "github.com/ethereum/go-ethereum/eth/gasprice" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/node" + "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/p2p/enode" + "github.com/ethereum/go-ethereum/p2p/nat" + "github.com/ethereum/go-ethereum/params" + "github.com/hashicorp/hcl/v2/hclsimple" + "github.com/imdario/mergo" + "github.com/mitchellh/go-homedir" + gopsutil "github.com/shirou/gopsutil/mem" +) + +type Config struct { + chain *chains.Chain + + // Chain is the chain to sync with + Chain string `hcl:"chain,optional"` + + // Name, or identity of the node + Name string `hcl:"name,optional"` + + // Whitelist is a list of required (block number, hash) pairs to accept + Whitelist map[string]string `hcl:"whitelist,optional"` + + // LogLevel is the level of the logs to put out + LogLevel string `hcl:"log-level,optional"` + + // DataDir is the directory to store the state in + DataDir string `hcl:"data-dir,optional"` + + // SyncMode selects the sync protocol + SyncMode string `hcl:"sync-mode,optional"` + + // GcMode selects the garbage collection mode for the trie + GcMode string `hcl:"gc-mode,optional"` + + // XXX + Snapshot bool `hcl:"snapshot,optional"` + + // Ethstats is the address of the ethstats server to send telemetry + Ethstats string `hcl:"ethstats,optional"` + + // P2P has the p2p network related settings + P2P *P2PConfig `hcl:"p2p,block"` + + // Heimdall has the heimdall connection related settings + Heimdall *HeimdallConfig `hcl:"heimdall,block"` + + // TxPool has the transaction pool related settings + TxPool *TxPoolConfig `hcl:"txpool,block"` + + // Sealer has the validator related settings + Sealer *SealerConfig `hcl:"sealer,block"` + + // JsonRPC has the json-rpc related settings + JsonRPC *JsonRPCConfig `hcl:"jsonrpc,block"` + + // Gpo has the gas price oracle related settings + Gpo *GpoConfig `hcl:"gpo,block"` + + // Telemetry has the telemetry related settings + Telemetry *TelemetryConfig `hcl:"telemetry,block"` + + // Cache has the cache related settings + Cache *CacheConfig `hcl:"cache,block"` + + // Account has the validator account related settings + Accounts *AccountsConfig `hcl:"accounts,block"` + + // GRPC has the grpc server related settings + GRPC *GRPCConfig +} + +type P2PConfig struct { + // MaxPeers sets the maximum number of connected peers + MaxPeers uint64 `hcl:"max-peers,optional"` + + // MaxPendPeers sets the maximum number of pending connected peers + MaxPendPeers uint64 `hcl:"max-pend-peers,optional"` + + // Bind is the bind address + Bind string `hcl:"bind,optional"` + + // Port is the port number + Port uint64 `hcl:"port,optional"` + + // NoDiscover is used to disable discovery + NoDiscover bool `hcl:"no-discover,optional"` + + // NAT it used to set NAT options + NAT string `hcl:"nat,optional"` + + // Discovery has the p2p discovery related settings + Discovery *P2PDiscovery `hcl:"discovery,block"` +} + +type P2PDiscovery struct { + // V5Enabled is used to enable disc v5 discovery mode + V5Enabled bool `hcl:"v5-enabled,optional"` + + // Bootnodes is the list of initial bootnodes + Bootnodes []string `hcl:"bootnodes,optional"` + + // BootnodesV4 is the list of initial v4 bootnodes + BootnodesV4 []string `hcl:"bootnodesv4,optional"` + + // BootnodesV5 is the list of initial v5 bootnodes + BootnodesV5 []string `hcl:"bootnodesv5,optional"` + + // StaticNodes is the list of static nodes + StaticNodes []string `hcl:"static-nodes,optional"` + + // TrustedNodes is the list of trusted nodes + TrustedNodes []string `hcl:"trusted-nodes,optional"` + + // DNS is the list of enrtree:// URLs which will be queried for nodes to connect to + DNS []string `hcl:"dns,optional"` +} + +type HeimdallConfig struct { + // URL is the url of the heimdall server + URL string `hcl:"url,optional"` + + // Without is used to disable remote heimdall during testing + Without bool `hcl:"without,optional"` +} + +type TxPoolConfig struct { + // Locals are the addresses that should be treated by default as local + Locals []string `hcl:"locals,optional"` + + // NoLocals enables whether local transaction handling should be disabled + NoLocals bool `hcl:"no-locals,optional"` + + // Journal is the path to store local transactions to survive node restarts + Journal string `hcl:"journal,optional"` + + // Rejournal is the time interval to regenerate the local transaction journal + Rejournal time.Duration + RejournalRaw string `hcl:"rejournal,optional"` + + // PriceLimit is the minimum gas price to enforce for acceptance into the pool + PriceLimit uint64 `hcl:"price-limit,optional"` + + // PriceBump is the minimum price bump percentage to replace an already existing transaction (nonce) + PriceBump uint64 `hcl:"price-bump,optional"` + + // AccountSlots is the number of executable transaction slots guaranteed per account + AccountSlots uint64 `hcl:"account-slots,optional"` + + // GlobalSlots is the maximum number of executable transaction slots for all accounts + GlobalSlots uint64 `hcl:"global-slots,optional"` + + // AccountQueue is the maximum number of non-executable transaction slots permitted per account + AccountQueue uint64 `hcl:"account-queue,optional"` + + // GlobalQueueis the maximum number of non-executable transaction slots for all accounts + GlobalQueue uint64 `hcl:"global-queue,optional"` + + // Lifetime is the maximum amount of time non-executable transaction are queued + LifeTime time.Duration + LifeTimeRaw string `hcl:"lifetime,optional"` +} + +type SealerConfig struct { + // Enabled is used to enable validator mode + Enabled bool `hcl:"enabled,optional"` + + // Etherbase is the address of the validator + Etherbase string `hcl:"etherbase,optional"` + + // ExtraData is the block extra data set by the miner + ExtraData string `hcl:"extra-data,optional"` + + // GasCeil is the target gas ceiling for mined blocks. + GasCeil uint64 `hcl:"gas-ceil,optional"` + + // GasPrice is the minimum gas price for mining a transaction + GasPrice *big.Int + GasPriceRaw string `hcl:"gas-price,optional"` +} + +type JsonRPCConfig struct { + // IPCDisable enables whether ipc is enabled or not + IPCDisable bool `hcl:"ipc-disable,optional"` + + // IPCPath is the path of the ipc endpoint + IPCPath string `hcl:"ipc-path,optional"` + + // Modules is the list of enabled api modules + Modules []string `hcl:"modules,optional"` + + // VHost is the list of valid virtual hosts + VHost []string `hcl:"vhost,optional"` + + // Cors is the list of Cors endpoints + Cors []string `hcl:"cors,optional"` + + // GasCap is the global gas cap for eth-call variants. + GasCap uint64 `hcl:"gas-cap,optional"` + + // TxFeeCap is the global transaction fee cap for send-transaction variants + TxFeeCap float64 `hcl:"tx-fee-cap,optional"` + + // Http has the json-rpc http related settings + Http *APIConfig `hcl:"http,block"` + + // Http has the json-rpc websocket related settings + Ws *APIConfig `hcl:"ws,block"` + + // Http has the json-rpc graphql related settings + Graphql *APIConfig `hcl:"graphql,block"` +} + +type GRPCConfig struct { + // Addr is the bind address for the grpc rpc server + Addr string +} + +type APIConfig struct { + // Enabled selects whether the api is enabled + Enabled bool `hcl:"enabled,optional"` + + // Port is the port number for this api + Port uint64 `hcl:"port,optional"` + + // Prefix is the http prefix to expose this api + Prefix string `hcl:"prefix,optional"` + + // Host is the address to bind the api + Host string `hcl:"host,optional"` +} + +type GpoConfig struct { + // Blocks is the number of blocks to track to compute the price oracle + Blocks uint64 `hcl:"blocks,optional"` + + // Percentile sets the weights to new blocks + Percentile uint64 `hcl:"percentile,optional"` + + // MaxPrice is an upper bound gas price + MaxPrice *big.Int + MaxPriceRaw string `hcl:"max-price,optional"` + + // IgnorePrice is a lower bound gas price + IgnorePrice *big.Int + IgnorePriceRaw string `hcl:"ignore-price,optional"` +} + +type TelemetryConfig struct { + // Enabled enables metrics + Enabled bool `hcl:"enabled,optional"` + + // Expensive enables expensive metrics + Expensive bool `hcl:"expensive,optional"` + + // InfluxDB has the influxdb related settings + InfluxDB *InfluxDBConfig `hcl:"influx,block"` + + // Prometheus Address + PrometheusAddr string `hcl:"prometheus-addr,optional"` + + // Open collector endpoint + OpenCollectorEndpoint string `hcl:"opencollector-endpoint,optional"` +} + +type InfluxDBConfig struct { + // V1Enabled enables influx v1 mode + V1Enabled bool `hcl:"v1-enabled,optional"` + + // Endpoint is the url endpoint of the influxdb service + Endpoint string `hcl:"endpoint,optional"` + + // Database is the name of the database in Influxdb to store the metrics. + Database string `hcl:"database,optional"` + + // Enabled is the username to authorize access to Influxdb + Username string `hcl:"username,optional"` + + // Password is the password to authorize access to Influxdb + Password string `hcl:"password,optional"` + + // Tags are tags attaches to all generated metrics + Tags map[string]string `hcl:"tags,optional"` + + // Enabled enables influx v2 mode + V2Enabled bool `hcl:"v2-enabled,optional"` + + // Token is the token to authorize access to Influxdb V2. + Token string `hcl:"token,optional"` + + // Bucket is the bucket to store metrics in Influxdb V2. + Bucket string `hcl:"bucket,optional"` + + // Organization is the name of the organization for Influxdb V2. + Organization string `hcl:"organization,optional"` +} + +type CacheConfig struct { + // Cache is the amount of cache of the node + Cache uint64 `hcl:"cache,optional"` + + // PercGc is percentage of cache used for garbage collection + PercGc uint64 `hcl:"perc-gc,optional"` + + // PercSnapshot is percentage of cache used for snapshots + PercSnapshot uint64 `hcl:"perc-snapshot,optional"` + + // PercDatabase is percentage of cache used for the database + PercDatabase uint64 `hcl:"perc-database,optional"` + + // PercTrie is percentage of cache used for the trie + PercTrie uint64 `hcl:"perc-trie,optional"` + + // Journal is the disk journal directory for trie cache to survive node restarts + Journal string `hcl:"journal,optional"` + + // Rejournal is the time interval to regenerate the journal for clean cache + Rejournal time.Duration + RejournalRaw string `hcl:"rejournal,optional"` + + // NoPrefetch is used to disable prefetch of tries + NoPrefetch bool `hcl:"no-prefetch,optional"` + + // Preimages is used to enable the track of hash preimages + Preimages bool `hcl:"preimages,optional"` + + // TxLookupLimit sets the maximum number of blocks from head whose tx indices are reserved. + TxLookupLimit uint64 `hcl:"tx-lookup-limit,optional"` +} + +type AccountsConfig struct { + // Unlock is the list of addresses to unlock in the node + Unlock []string `hcl:"unlock,optional"` + + // PasswordFile is the file where the account passwords are stored + PasswordFile string `hcl:"password-file,optional"` + + // AllowInsecureUnlock allows user to unlock accounts in unsafe http environment. + AllowInsecureUnlock bool `hcl:"allow-insecure-unlock,optional"` + + // UseLightweightKDF enables a faster but less secure encryption of accounts + UseLightweightKDF bool `hcl:"use-lightweight-kdf,optional"` +} + +func DefaultConfig() *Config { + return &Config{ + Chain: "mainnet", + Name: Hostname(), + Whitelist: map[string]string{}, + LogLevel: "INFO", + DataDir: defaultDataDir(), + P2P: &P2PConfig{ + MaxPeers: 30, + MaxPendPeers: 50, + Bind: "0.0.0.0", + Port: 30303, + NoDiscover: false, + NAT: "any", + Discovery: &P2PDiscovery{ + V5Enabled: false, + Bootnodes: []string{}, + BootnodesV4: []string{}, + BootnodesV5: []string{}, + StaticNodes: []string{}, + TrustedNodes: []string{}, + DNS: []string{}, + }, + }, + Heimdall: &HeimdallConfig{ + URL: "http://localhost:1317", + Without: false, + }, + SyncMode: "full", + GcMode: "full", + Snapshot: true, + TxPool: &TxPoolConfig{ + Locals: []string{}, + NoLocals: false, + Journal: "", + Rejournal: time.Duration(1 * time.Hour), + PriceLimit: 1, + PriceBump: 10, + AccountSlots: 16, + GlobalSlots: 4096, + AccountQueue: 64, + GlobalQueue: 1024, + LifeTime: time.Duration(3 * time.Hour), + }, + Sealer: &SealerConfig{ + Enabled: false, + Etherbase: "", + GasCeil: 8000000, + GasPrice: big.NewInt(params.GWei), + ExtraData: "", + }, + Gpo: &GpoConfig{ + Blocks: 20, + Percentile: 60, + MaxPrice: gasprice.DefaultMaxPrice, + IgnorePrice: gasprice.DefaultIgnorePrice, + }, + JsonRPC: &JsonRPCConfig{ + IPCDisable: false, + IPCPath: "", + Modules: []string{"web3", "net"}, + Cors: []string{"*"}, + VHost: []string{"*"}, + GasCap: ethconfig.Defaults.RPCGasCap, + TxFeeCap: ethconfig.Defaults.RPCTxFeeCap, + Http: &APIConfig{ + Enabled: false, + Port: 8545, + Prefix: "", + Host: "localhost", + }, + Ws: &APIConfig{ + Enabled: false, + Port: 8546, + Prefix: "", + Host: "localhost", + }, + Graphql: &APIConfig{ + Enabled: false, + }, + }, + Ethstats: "", + Telemetry: &TelemetryConfig{ + Enabled: false, + Expensive: false, + PrometheusAddr: "", + OpenCollectorEndpoint: "", + InfluxDB: &InfluxDBConfig{ + V1Enabled: false, + Endpoint: "", + Database: "", + Username: "", + Password: "", + Tags: map[string]string{}, + V2Enabled: false, + Token: "", + Bucket: "", + Organization: "", + }, + }, + Cache: &CacheConfig{ + Cache: 1024, + PercDatabase: 50, + PercTrie: 15, + PercGc: 25, + PercSnapshot: 10, + Journal: "triecache", + Rejournal: 60 * time.Minute, + NoPrefetch: false, + Preimages: false, + TxLookupLimit: 2350000, + }, + Accounts: &AccountsConfig{ + Unlock: []string{}, + PasswordFile: "", + AllowInsecureUnlock: false, + UseLightweightKDF: false, + }, + GRPC: &GRPCConfig{ + Addr: ":3131", + }, + } +} + +func (c *Config) fillBigInt() error { + tds := []struct { + path string + td **big.Int + str *string + }{ + {"gpo.maxprice", &c.Gpo.MaxPrice, &c.Gpo.MaxPriceRaw}, + {"gpo.ignoreprice", &c.Gpo.IgnorePrice, &c.Gpo.IgnorePriceRaw}, + {"sealer.gasprice", &c.Sealer.GasPrice, &c.Sealer.GasPriceRaw}, + } + + for _, x := range tds { + if *x.str != "" { + b := new(big.Int) + + var ok bool + if strings.HasPrefix(*x.str, "0x") { + b, ok = b.SetString((*x.str)[2:], 16) + } else { + b, ok = b.SetString(*x.str, 10) + } + if !ok { + return fmt.Errorf("%s can't parse big int %s", x.path, *x.str) + } + *x.str = "" + *x.td = b + } + } + return nil +} + +func (c *Config) fillTimeDurations() error { + tds := []struct { + path string + td *time.Duration + str *string + }{ + {"txpool.lifetime", &c.TxPool.LifeTime, &c.TxPool.LifeTimeRaw}, + {"txpool.rejournal", &c.TxPool.Rejournal, &c.TxPool.RejournalRaw}, + {"cache.rejournal", &c.Cache.Rejournal, &c.Cache.RejournalRaw}, + } + + for _, x := range tds { + if x.td != nil && x.str != nil && *x.str != "" { + d, err := time.ParseDuration(*x.str) + if err != nil { + return fmt.Errorf("%s can't parse time duration %s", x.path, *x.str) + } + *x.str = "" + *x.td = d + } + } + return nil +} + +func readConfigFile(path string) (*Config, error) { + ext := filepath.Ext(path) + if ext == ".toml" { + // read file and apply the legacy config + data, err := ioutil.ReadFile(path) + if err != nil { + return nil, err + } + return readLegacyConfig(data) + } + + config := &Config{ + TxPool: &TxPoolConfig{}, + Cache: &CacheConfig{}, + Sealer: &SealerConfig{}, + } + if err := hclsimple.DecodeFile(path, nil, config); err != nil { + return nil, fmt.Errorf("failed to decode config file '%s': %v", path, err) + } + if err := config.fillBigInt(); err != nil { + return nil, err + } + if err := config.fillTimeDurations(); err != nil { + return nil, err + } + return config, nil +} + +func (c *Config) loadChain() error { + chain, ok := chains.GetChain(c.Chain) + if !ok { + return fmt.Errorf("chain '%s' not found", c.Chain) + } + c.chain = chain + + // preload some default values that depend on the chain file + if c.P2P.Discovery.DNS == nil { + c.P2P.Discovery.DNS = c.chain.DNS + } + + // depending on the chain we have different cache values + if c.Chain != "mainnet" { + c.Cache.Cache = 4096 + } else { + c.Cache.Cache = 1024 + } + return nil +} + +func (c *Config) buildEth() (*ethconfig.Config, error) { + dbHandles, err := makeDatabaseHandles() + if err != nil { + return nil, err + } + n := ethconfig.Defaults + n.NetworkId = c.chain.NetworkId + n.Genesis = c.chain.Genesis + n.HeimdallURL = c.Heimdall.URL + n.WithoutHeimdall = c.Heimdall.Without + + // gas price oracle + { + n.GPO.Blocks = int(c.Gpo.Blocks) + n.GPO.Percentile = int(c.Gpo.Percentile) + n.GPO.MaxPrice = c.Gpo.MaxPrice + n.GPO.IgnorePrice = c.Gpo.IgnorePrice + } + + // txpool options + { + n.TxPool.NoLocals = c.TxPool.NoLocals + n.TxPool.Journal = c.TxPool.Journal + n.TxPool.Rejournal = c.TxPool.Rejournal + n.TxPool.PriceLimit = c.TxPool.PriceLimit + n.TxPool.PriceBump = c.TxPool.PriceBump + n.TxPool.AccountSlots = c.TxPool.AccountSlots + n.TxPool.GlobalSlots = c.TxPool.GlobalSlots + n.TxPool.AccountQueue = c.TxPool.AccountQueue + n.TxPool.GlobalQueue = c.TxPool.GlobalQueue + n.TxPool.Lifetime = c.TxPool.LifeTime + } + + // miner options + { + n.Miner.GasPrice = c.Sealer.GasPrice + n.Miner.GasCeil = c.Sealer.GasCeil + n.Miner.ExtraData = []byte(c.Sealer.ExtraData) + + if etherbase := c.Sealer.Etherbase; etherbase != "" { + if !common.IsHexAddress(etherbase) { + return nil, fmt.Errorf("etherbase is not an address: %s", etherbase) + } + n.Miner.Etherbase = common.HexToAddress(etherbase) + } + } + + // discovery (this params should be in node.Config) + { + n.EthDiscoveryURLs = c.P2P.Discovery.DNS + n.SnapDiscoveryURLs = c.P2P.Discovery.DNS + } + + // whitelist + { + n.Whitelist = map[uint64]common.Hash{} + for k, v := range c.Whitelist { + number, err := strconv.ParseUint(k, 0, 64) + if err != nil { + return nil, fmt.Errorf("invalid whitelist block number %s: %v", k, err) + } + var hash common.Hash + if err = hash.UnmarshalText([]byte(v)); err != nil { + return nil, fmt.Errorf("invalid whitelist hash %s: %v", v, err) + } + n.Whitelist[number] = hash + } + } + + // cache + { + cache := c.Cache.Cache + calcPerc := func(val uint64) int { + return int(cache * (val) / 100) + } + + // Cap the cache allowance + mem, err := gopsutil.VirtualMemory() + if err == nil { + if 32<<(^uintptr(0)>>63) == 32 && mem.Total > 2*1024*1024*1024 { + log.Warn("Lowering memory allowance on 32bit arch", "available", mem.Total/1024/1024, "addressable", 2*1024) + mem.Total = 2 * 1024 * 1024 * 1024 + } + allowance := uint64(mem.Total / 1024 / 1024 / 3) + if cache > allowance { + log.Warn("Sanitizing cache to Go's GC limits", "provided", cache, "updated", allowance) + cache = allowance + } + } + // Tune the garbage collector + gogc := math.Max(20, math.Min(100, 100/(float64(cache)/1024))) + + log.Debug("Sanitizing Go's GC trigger", "percent", int(gogc)) + godebug.SetGCPercent(int(gogc)) + + n.TrieCleanCacheJournal = c.Cache.Journal + n.TrieCleanCacheRejournal = c.Cache.Rejournal + n.DatabaseCache = calcPerc(c.Cache.PercDatabase) + n.SnapshotCache = calcPerc(c.Cache.PercSnapshot) + n.TrieCleanCache = calcPerc(c.Cache.PercTrie) + n.TrieDirtyCache = calcPerc(c.Cache.PercGc) + n.NoPrefetch = c.Cache.NoPrefetch + n.Preimages = c.Cache.Preimages + n.TxLookupLimit = c.Cache.TxLookupLimit + } + + n.RPCGasCap = c.JsonRPC.GasCap + if n.RPCGasCap != 0 { + log.Info("Set global gas cap", "cap", n.RPCGasCap) + } else { + log.Info("Global gas cap disabled") + } + n.RPCTxFeeCap = c.JsonRPC.TxFeeCap + + // sync mode. It can either be "fast", "full" or "snap". We disable + // for now the "light" mode. + switch c.SyncMode { + case "fast": + n.SyncMode = downloader.FastSync + case "full": + n.SyncMode = downloader.FullSync + case "snap": + n.SyncMode = downloader.SnapSync + default: + return nil, fmt.Errorf("sync mode '%s' not found", c.SyncMode) + } + + // archive mode. It can either be "archive" or "full". + switch c.GcMode { + case "full": + n.NoPruning = false + case "archive": + n.NoPruning = true + if !n.Preimages { + n.Preimages = true + log.Info("Enabling recording of key preimages since archive mode is used") + } + default: + return nil, fmt.Errorf("gcmode '%s' not found", c.GcMode) + } + + // snapshot disable check + if c.Snapshot { + if n.SyncMode == downloader.SnapSync { + log.Info("Snap sync requested, enabling --snapshot") + } else { + // disable snapshot + n.TrieCleanCache += n.SnapshotCache + n.SnapshotCache = 0 + } + } + + n.DatabaseHandles = dbHandles + return &n, nil +} + +var ( + clientIdentifier = "bor" + gitCommit = "" // Git SHA1 commit hash of the release (set via linker flags) + gitDate = "" // Git commit date YYYYMMDD of the release (set via linker flags) +) + +func (c *Config) buildNode() (*node.Config, error) { + ipcPath := "" + if !c.JsonRPC.IPCDisable { + ipcPath = clientIdentifier + ".ipc" + if c.JsonRPC.IPCPath != "" { + ipcPath = c.JsonRPC.IPCPath + } + } + + cfg := &node.Config{ + Name: clientIdentifier, + DataDir: c.DataDir, + UseLightweightKDF: c.Accounts.UseLightweightKDF, + InsecureUnlockAllowed: c.Accounts.AllowInsecureUnlock, + Version: params.VersionWithCommit(gitCommit, gitDate), + IPCPath: ipcPath, + P2P: p2p.Config{ + MaxPeers: int(c.P2P.MaxPeers), + MaxPendingPeers: int(c.P2P.MaxPendPeers), + ListenAddr: c.P2P.Bind + ":" + strconv.Itoa(int(c.P2P.Port)), + DiscoveryV5: c.P2P.Discovery.V5Enabled, + }, + HTTPModules: c.JsonRPC.Modules, + HTTPCors: c.JsonRPC.Cors, + HTTPVirtualHosts: c.JsonRPC.VHost, + HTTPPathPrefix: c.JsonRPC.Http.Prefix, + WSModules: c.JsonRPC.Modules, + WSOrigins: c.JsonRPC.Cors, + WSPathPrefix: c.JsonRPC.Ws.Prefix, + GraphQLCors: c.JsonRPC.Cors, + GraphQLVirtualHosts: c.JsonRPC.VHost, + } + + // enable jsonrpc endpoints + { + if c.JsonRPC.Http.Enabled { + cfg.HTTPHost = c.JsonRPC.Http.Host + cfg.HTTPPort = int(c.JsonRPC.Http.Port) + } + if c.JsonRPC.Ws.Enabled { + cfg.WSHost = c.JsonRPC.Ws.Host + cfg.WSPort = int(c.JsonRPC.Ws.Port) + } + } + + natif, err := nat.Parse(c.P2P.NAT) + if err != nil { + return nil, fmt.Errorf("wrong 'nat' flag: %v", err) + } + cfg.P2P.NAT = natif + + // Discovery + // if no bootnodes are defined, use the ones from the chain file. + bootnodes := c.P2P.Discovery.Bootnodes + if len(bootnodes) == 0 { + bootnodes = c.chain.Bootnodes + } + if cfg.P2P.BootstrapNodes, err = parseBootnodes(bootnodes); err != nil { + return nil, err + } + if cfg.P2P.BootstrapNodesV5, err = parseBootnodes(c.P2P.Discovery.BootnodesV5); err != nil { + return nil, err + } + if cfg.P2P.StaticNodes, err = parseBootnodes(c.P2P.Discovery.StaticNodes); err != nil { + return nil, err + } + if cfg.P2P.TrustedNodes, err = parseBootnodes(c.P2P.Discovery.TrustedNodes); err != nil { + return nil, err + } + + if c.P2P.NoDiscover { + // Disable networking, for now, we will not even allow incomming connections + cfg.P2P.MaxPeers = 0 + cfg.P2P.NoDiscovery = true + } + return cfg, nil +} + +func (c *Config) Merge(cc ...*Config) error { + for _, elem := range cc { + if err := mergo.Merge(c, elem, mergo.WithOverride, mergo.WithAppendSlice); err != nil { + return fmt.Errorf("failed to merge configurations: %v", err) + } + } + return nil +} + +func makeDatabaseHandles() (int, error) { + limit, err := fdlimit.Maximum() + if err != nil { + return -1, err + } + raised, err := fdlimit.Raise(uint64(limit)) + if err != nil { + return -1, err + } + return int(raised / 2), nil +} + +func parseBootnodes(urls []string) ([]*enode.Node, error) { + dst := []*enode.Node{} + for _, url := range urls { + if url != "" { + node, err := enode.Parse(enode.ValidSchemes, url) + if err != nil { + return nil, fmt.Errorf("invalid bootstrap url '%s': %v", url, err) + } + dst = append(dst, node) + } + } + return dst, nil +} + +func defaultDataDir() string { + // Try to place the data folder in the user's home dir + home, _ := homedir.Dir() + if home == "" { + // we cannot guess a stable location + return "" + } + switch runtime.GOOS { + case "darwin": + return filepath.Join(home, "Library", "Bor") + case "windows": + appdata := os.Getenv("LOCALAPPDATA") + if appdata == "" { + // Windows XP and below don't have LocalAppData. + panic("environment variable LocalAppData is undefined") + } + return filepath.Join(appdata, "Bor") + default: + return filepath.Join(home, ".bor") + } +} + +func Hostname() string { + hostname, err := os.Hostname() + if err != nil { + return "bor" + } + return hostname +} diff --git a/command/server/config_legacy.go b/command/server/config_legacy.go new file mode 100644 index 0000000000000000000000000000000000000000..0d96b2e023f9b058d01d883aba785aa333d6e353 --- /dev/null +++ b/command/server/config_legacy.go @@ -0,0 +1,33 @@ +package server + +import ( + "bytes" + + "github.com/naoina/toml" +) + +type legacyConfig struct { + Node struct { + P2P struct { + StaticNodes []string + TrustedNodes []string + } + } +} + +func (l *legacyConfig) Config() *Config { + c := DefaultConfig() + c.P2P.Discovery.StaticNodes = l.Node.P2P.StaticNodes + c.P2P.Discovery.TrustedNodes = l.Node.P2P.TrustedNodes + return c +} + +func readLegacyConfig(data []byte) (*Config, error) { + var legacy legacyConfig + + r := toml.NewDecoder(bytes.NewReader(data)) + if err := r.Decode(&legacy); err != nil { + return nil, err + } + return legacy.Config(), nil +} diff --git a/command/server/config_legacy_test.go b/command/server/config_legacy_test.go new file mode 100644 index 0000000000000000000000000000000000000000..399481fc9bcd14e50bb362e3ce0a4d9dae85ba18 --- /dev/null +++ b/command/server/config_legacy_test.go @@ -0,0 +1,21 @@ +package server + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestConfigLegacy(t *testing.T) { + toml := `[Node.P2P] +StaticNodes = ["node1"] +TrustedNodes = ["node2"]` + + config, err := readLegacyConfig([]byte(toml)) + if err != nil { + t.Fatal(err) + } + + assert.Equal(t, config.P2P.Discovery.StaticNodes, []string{"node1"}) + assert.Equal(t, config.P2P.Discovery.TrustedNodes, []string{"node2"}) +} diff --git a/command/server/config_test.go b/command/server/config_test.go new file mode 100644 index 0000000000000000000000000000000000000000..6383c3e0035d27d3c9e8e63368214080473a8729 --- /dev/null +++ b/command/server/config_test.go @@ -0,0 +1,133 @@ +package server + +import ( + "math/big" + "testing" + "time" + + "github.com/stretchr/testify/assert" +) + +func TestConfigDefault(t *testing.T) { + // the default config should work out of the box + config := DefaultConfig() + assert.NoError(t, config.loadChain()) + + _, err := config.buildNode() + assert.NoError(t, err) + + _, err = config.buildEth() + assert.NoError(t, err) +} + +func TestConfigMerge(t *testing.T) { + c0 := &Config{ + Chain: "0", + Snapshot: true, + Whitelist: map[string]string{ + "a": "b", + }, + TxPool: &TxPoolConfig{ + LifeTime: 5 * time.Second, + }, + P2P: &P2PConfig{ + Discovery: &P2PDiscovery{ + StaticNodes: []string{ + "a", + }, + }, + }, + } + c1 := &Config{ + Chain: "1", + Whitelist: map[string]string{ + "b": "c", + }, + P2P: &P2PConfig{ + MaxPeers: 10, + Discovery: &P2PDiscovery{ + StaticNodes: []string{ + "b", + }, + }, + }, + } + expected := &Config{ + Chain: "1", + Snapshot: true, + Whitelist: map[string]string{ + "a": "b", + "b": "c", + }, + TxPool: &TxPoolConfig{ + LifeTime: 5 * time.Second, + }, + P2P: &P2PConfig{ + MaxPeers: 10, + Discovery: &P2PDiscovery{ + StaticNodes: []string{ + "a", + "b", + }, + }, + }, + } + assert.NoError(t, c0.Merge(c1)) + assert.Equal(t, c0, expected) +} + +func TestConfigLoadFile(t *testing.T) { + readFile := func(path string) { + config, err := readConfigFile(path) + assert.NoError(t, err) + assert.Equal(t, config, &Config{ + DataDir: "./data", + Whitelist: map[string]string{ + "a": "b", + }, + P2P: &P2PConfig{ + MaxPeers: 30, + }, + TxPool: &TxPoolConfig{ + LifeTime: time.Duration(1 * time.Second), + }, + Gpo: &GpoConfig{ + MaxPrice: big.NewInt(100), + }, + Sealer: &SealerConfig{}, + Cache: &CacheConfig{}, + }) + } + + // read file in hcl format + t.Run("hcl", func(t *testing.T) { + readFile("./testdata/simple.hcl") + }) + // read file in json format + t.Run("json", func(t *testing.T) { + readFile("./testdata/simple.json") + }) +} + +var dummyEnodeAddr = "enode://0cb82b395094ee4a2915e9714894627de9ed8498fb881cec6db7c65e8b9a5bd7f2f25cc84e71e89d0947e51c76e85d0847de848c7782b13c0255247a6758178c@44.232.55.71:30303" + +func TestConfigBootnodesDefault(t *testing.T) { + t.Run("EmptyBootnodes", func(t *testing.T) { + // if no bootnodes are specific, we use the ones from the genesis chain + config := DefaultConfig() + assert.NoError(t, config.loadChain()) + + cfg, err := config.buildNode() + assert.NoError(t, err) + assert.NotEmpty(t, cfg.P2P.BootstrapNodes) + }) + t.Run("NotEmptyBootnodes", func(t *testing.T) { + // if bootnodes specific, DO NOT load the genesis bootnodes + config := DefaultConfig() + config.P2P.Discovery.Bootnodes = []string{dummyEnodeAddr} + + cfg, err := config.buildNode() + assert.NoError(t, err) + assert.Len(t, cfg.P2P.BootstrapNodes, 1) + }) +} diff --git a/command/server/flags.go b/command/server/flags.go new file mode 100644 index 0000000000000000000000000000000000000000..76828ef6fcb0c6e761259722e4c6f7f39a75f007 --- /dev/null +++ b/command/server/flags.go @@ -0,0 +1,465 @@ +package server + +import ( + "github.com/ethereum/go-ethereum/command/flagset" +) + +func (c *Command) Flags() *flagset.Flagset { + c.cliConfig = DefaultConfig() + + f := flagset.NewFlagSet("server") + + f.StringFlag(&flagset.StringFlag{ + Name: "chain", + Usage: "Name of the chain to sync", + Value: &c.cliConfig.Chain, + }) + f.StringFlag(&flagset.StringFlag{ + Name: "name", + Usage: "Name/Identity of the node", + Value: &c.cliConfig.Name, + }) + f.StringFlag(&flagset.StringFlag{ + Name: "log-level", + Usage: "Set log level for the server", + Value: &c.cliConfig.LogLevel, + }) + f.StringFlag(&flagset.StringFlag{ + Name: "datadir", + Usage: "Path of the data directory to store information", + Value: &c.cliConfig.DataDir, + }) + f.SliceStringFlag(&flagset.SliceStringFlag{ + Name: "config", + Usage: "File for the config file", + Value: &c.configFile, + }) + f.StringFlag(&flagset.StringFlag{ + Name: "syncmode", + Usage: `Blockchain sync mode ("fast", "full", "snap" or "light")`, + Value: &c.cliConfig.SyncMode, + }) + f.StringFlag(&flagset.StringFlag{ + Name: "gcmode", + Usage: `Blockchain garbage collection mode ("full", "archive")`, + Value: &c.cliConfig.GcMode, + }) + f.MapStringFlag(&flagset.MapStringFlag{ + Name: "whitelist", + Usage: "Comma separated block number-to-hash mappings to enforce (<number>=<hash>)", + Value: &c.cliConfig.Whitelist, + }) + f.BoolFlag(&flagset.BoolFlag{ + Name: "snapshot", + Usage: `Enables snapshot-database mode (default = enable)`, + Value: &c.cliConfig.Snapshot, + }) + + // heimdall + f.StringFlag(&flagset.StringFlag{ + Name: "bor.heimdall", + Usage: "URL of Heimdall service", + Value: &c.cliConfig.Heimdall.URL, + }) + f.BoolFlag(&flagset.BoolFlag{ + Name: "bor.withoutheimdall", + Usage: "Run without Heimdall service (for testing purpose)", + Value: &c.cliConfig.Heimdall.Without, + }) + + // txpool options + f.SliceStringFlag(&flagset.SliceStringFlag{ + Name: "txpool.locals", + Usage: "Comma separated accounts to treat as locals (no flush, priority inclusion)", + Value: &c.cliConfig.TxPool.Locals, + }) + f.BoolFlag(&flagset.BoolFlag{ + Name: "txpool.nolocals", + Usage: "Disables price exemptions for locally submitted transactions", + Value: &c.cliConfig.TxPool.NoLocals, + }) + f.StringFlag(&flagset.StringFlag{ + Name: "txpool.journal", + Usage: "Disk journal for local transaction to survive node restarts", + Value: &c.cliConfig.TxPool.Journal, + }) + f.DurationFlag(&flagset.DurationFlag{ + Name: "txpool.rejournal", + Usage: "Time interval to regenerate the local transaction journal", + Value: &c.cliConfig.TxPool.Rejournal, + }) + f.Uint64Flag(&flagset.Uint64Flag{ + Name: "txpool.pricelimit", + Usage: "Minimum gas price limit to enforce for acceptance into the pool", + Value: &c.cliConfig.TxPool.PriceLimit, + }) + f.Uint64Flag(&flagset.Uint64Flag{ + Name: "txpool.pricebump", + Usage: "Price bump percentage to replace an already existing transaction", + Value: &c.cliConfig.TxPool.PriceBump, + }) + f.Uint64Flag(&flagset.Uint64Flag{ + Name: "txpool.accountslots", + Usage: "Minimum number of executable transaction slots guaranteed per account", + Value: &c.cliConfig.TxPool.AccountSlots, + }) + f.Uint64Flag(&flagset.Uint64Flag{ + Name: "txpool.globalslots", + Usage: "Maximum number of executable transaction slots for all accounts", + Value: &c.cliConfig.TxPool.GlobalSlots, + }) + f.Uint64Flag(&flagset.Uint64Flag{ + Name: "txpool.accountqueue", + Usage: "Maximum number of non-executable transaction slots permitted per account", + Value: &c.cliConfig.TxPool.AccountQueue, + }) + f.Uint64Flag(&flagset.Uint64Flag{ + Name: "txpool.globalqueue", + Usage: "Maximum number of non-executable transaction slots for all accounts", + Value: &c.cliConfig.TxPool.GlobalQueue, + }) + f.DurationFlag(&flagset.DurationFlag{ + Name: "txpool.lifetime", + Usage: "Maximum amount of time non-executable transaction are queued", + Value: &c.cliConfig.TxPool.LifeTime, + }) + + // sealer options + f.BoolFlag(&flagset.BoolFlag{ + Name: "mine", + Usage: "Enable mining", + Value: &c.cliConfig.Sealer.Enabled, + }) + f.StringFlag(&flagset.StringFlag{ + Name: "miner.etherbase", + Usage: "Public address for block mining rewards (default = first account)", + Value: &c.cliConfig.Sealer.Etherbase, + }) + f.StringFlag(&flagset.StringFlag{ + Name: "miner.extradata", + Usage: "Block extra data set by the miner (default = client version)", + Value: &c.cliConfig.Sealer.ExtraData, + }) + f.Uint64Flag(&flagset.Uint64Flag{ + Name: "miner.gaslimit", + Usage: "Target gas ceiling for mined blocks", + Value: &c.cliConfig.Sealer.GasCeil, + }) + f.BigIntFlag(&flagset.BigIntFlag{ + Name: "miner.gasprice", + Usage: "Minimum gas price for mining a transaction", + Value: c.cliConfig.Sealer.GasPrice, + }) + + // ethstats + f.StringFlag(&flagset.StringFlag{ + Name: "ethstats", + Usage: "Reporting URL of a ethstats service (nodename:secret@host:port)", + Value: &c.cliConfig.Ethstats, + }) + + // gas price oracle + f.Uint64Flag(&flagset.Uint64Flag{ + Name: "gpo.blocks", + Usage: "Number of recent blocks to check for gas prices", + Value: &c.cliConfig.Gpo.Blocks, + }) + f.Uint64Flag(&flagset.Uint64Flag{ + Name: "gpo.percentile", + Usage: "Suggested gas price is the given percentile of a set of recent transaction gas prices", + Value: &c.cliConfig.Gpo.Percentile, + }) + f.BigIntFlag(&flagset.BigIntFlag{ + Name: "gpo.maxprice", + Usage: "Maximum gas price will be recommended by gpo", + Value: c.cliConfig.Gpo.MaxPrice, + }) + f.BigIntFlag(&flagset.BigIntFlag{ + Name: "gpo.ignoreprice", + Usage: "Gas price below which gpo will ignore transactions", + Value: c.cliConfig.Gpo.IgnorePrice, + }) + + // cache options + f.Uint64Flag(&flagset.Uint64Flag{ + Name: "cache", + Usage: "Megabytes of memory allocated to internal caching (default = 4096 mainnet full node)", + Value: &c.cliConfig.Cache.Cache, + }) + f.Uint64Flag(&flagset.Uint64Flag{ + Name: "cache.database", + Usage: "Percentage of cache memory allowance to use for database io", + Value: &c.cliConfig.Cache.PercDatabase, + }) + f.Uint64Flag(&flagset.Uint64Flag{ + Name: "cache.trie", + Usage: "Percentage of cache memory allowance to use for trie caching (default = 15% full mode, 30% archive mode)", + Value: &c.cliConfig.Cache.PercTrie, + }) + f.StringFlag(&flagset.StringFlag{ + Name: "cache.trie.journal", + Usage: "Disk journal directory for trie cache to survive node restarts", + Value: &c.cliConfig.Cache.Journal, + }) + f.DurationFlag(&flagset.DurationFlag{ + Name: "cache.trie.rejournal", + Usage: "Time interval to regenerate the trie cache journal", + Value: &c.cliConfig.Cache.Rejournal, + }) + f.Uint64Flag(&flagset.Uint64Flag{ + Name: "cache.gc", + Usage: "Percentage of cache memory allowance to use for trie pruning (default = 25% full mode, 0% archive mode)", + Value: &c.cliConfig.Cache.PercGc, + }) + f.Uint64Flag(&flagset.Uint64Flag{ + Name: "cache.snapshot", + Usage: "Percentage of cache memory allowance to use for snapshot caching (default = 10% full mode, 20% archive mode)", + Value: &c.cliConfig.Cache.PercSnapshot, + }) + f.BoolFlag(&flagset.BoolFlag{ + Name: "cache.noprefetch", + Usage: "Disable heuristic state prefetch during block import (less CPU and disk IO, more time waiting for data)", + Value: &c.cliConfig.Cache.NoPrefetch, + }) + f.BoolFlag(&flagset.BoolFlag{ + Name: "cache.preimages", + Usage: "Enable recording the SHA3/keccak preimages of trie keys", + Value: &c.cliConfig.Cache.Preimages, + }) + f.Uint64Flag(&flagset.Uint64Flag{ + Name: "txlookuplimit", + Usage: "Number of recent blocks to maintain transactions index for (default = about one year, 0 = entire chain)", + Value: &c.cliConfig.Cache.TxLookupLimit, + }) + + // rpc options + f.Uint64Flag(&flagset.Uint64Flag{ + Name: "rpc.gascap", + Usage: "Sets a cap on gas that can be used in eth_call/estimateGas (0=infinite)", + Value: &c.cliConfig.JsonRPC.GasCap, + }) + f.Float64Flag(&flagset.Float64Flag{ + Name: "rpc.txfeecap", + Usage: "Sets a cap on transaction fee (in ether) that can be sent via the RPC APIs (0 = no cap)", + Value: &c.cliConfig.JsonRPC.TxFeeCap, + }) + f.BoolFlag(&flagset.BoolFlag{ + Name: "ipcdisable", + Usage: "Disable the IPC-RPC server", + Value: &c.cliConfig.JsonRPC.IPCDisable, + }) + f.StringFlag(&flagset.StringFlag{ + Name: "ipcpath", + Usage: "Filename for IPC socket/pipe within the datadir (explicit paths escape it)", + Value: &c.cliConfig.JsonRPC.IPCPath, + }) + f.SliceStringFlag(&flagset.SliceStringFlag{ + Name: "jsonrpc.corsdomain", + Usage: "Comma separated list of domains from which to accept cross origin requests (browser enforced)", + Value: &c.cliConfig.JsonRPC.Cors, + }) + f.SliceStringFlag(&flagset.SliceStringFlag{ + Name: "jsonrpc.vhosts", + Usage: "Comma separated list of virtual hostnames from which to accept requests (server enforced). Accepts '*' wildcard.", + Value: &c.cliConfig.JsonRPC.VHost, + }) + f.SliceStringFlag(&flagset.SliceStringFlag{ + Name: "jsonrpc.modules", + Usage: "API's offered over the HTTP-RPC interface", + Value: &c.cliConfig.JsonRPC.Modules, + }) + + // http options + f.BoolFlag(&flagset.BoolFlag{ + Name: "http", + Usage: "Enable the HTTP-RPC server", + Value: &c.cliConfig.JsonRPC.Http.Enabled, + }) + f.StringFlag(&flagset.StringFlag{ + Name: "http.addr", + Usage: "HTTP-RPC server listening interface", + Value: &c.cliConfig.JsonRPC.Http.Host, + }) + f.Uint64Flag(&flagset.Uint64Flag{ + Name: "http.port", + Usage: "HTTP-RPC server listening port", + Value: &c.cliConfig.JsonRPC.Http.Port, + }) + f.StringFlag(&flagset.StringFlag{ + Name: "http.rpcprefix", + Usage: "HTTP path path prefix on which JSON-RPC is served. Use '/' to serve on all paths.", + Value: &c.cliConfig.JsonRPC.Http.Prefix, + }) + // ws options + f.BoolFlag(&flagset.BoolFlag{ + Name: "ws", + Usage: "Enable the WS-RPC server", + Value: &c.cliConfig.JsonRPC.Ws.Enabled, + }) + f.StringFlag(&flagset.StringFlag{ + Name: "ws.addr", + Usage: "WS-RPC server listening interface", + Value: &c.cliConfig.JsonRPC.Ws.Host, + }) + f.Uint64Flag(&flagset.Uint64Flag{ + Name: "ws.port", + Usage: "WS-RPC server listening port", + Value: &c.cliConfig.JsonRPC.Ws.Port, + }) + f.StringFlag(&flagset.StringFlag{ + Name: "ws.rpcprefix", + Usage: "HTTP path prefix on which JSON-RPC is served. Use '/' to serve on all paths.", + Value: &c.cliConfig.JsonRPC.Ws.Prefix, + }) + // graphql options + f.BoolFlag(&flagset.BoolFlag{ + Name: "graphql", + Usage: "Enable GraphQL on the HTTP-RPC server. Note that GraphQL can only be started if an HTTP server is started as well.", + Value: &c.cliConfig.JsonRPC.Graphql.Enabled, + }) + + // p2p options + f.StringFlag(&flagset.StringFlag{ + Name: "bind", + Usage: "Network binding address", + Value: &c.cliConfig.P2P.Bind, + }) + f.Uint64Flag(&flagset.Uint64Flag{ + Name: "port", + Usage: "Network listening port", + Value: &c.cliConfig.P2P.Port, + }) + f.SliceStringFlag(&flagset.SliceStringFlag{ + Name: "bootnodes", + Usage: "Comma separated enode URLs for P2P discovery bootstrap", + Value: &c.cliConfig.P2P.Discovery.Bootnodes, + }) + f.Uint64Flag(&flagset.Uint64Flag{ + Name: "maxpeers", + Usage: "Maximum number of network peers (network disabled if set to 0)", + Value: &c.cliConfig.P2P.MaxPeers, + }) + f.Uint64Flag(&flagset.Uint64Flag{ + Name: "maxpendpeers", + Usage: "Maximum number of pending connection attempts (defaults used if set to 0)", + Value: &c.cliConfig.P2P.MaxPendPeers, + }) + f.StringFlag(&flagset.StringFlag{ + Name: "nat", + Usage: "NAT port mapping mechanism (any|none|upnp|pmp|extip:<IP>)", + Value: &c.cliConfig.P2P.NAT, + }) + f.BoolFlag(&flagset.BoolFlag{ + Name: "nodiscover", + Usage: "Disables the peer discovery mechanism (manual peer addition)", + Value: &c.cliConfig.P2P.NoDiscover, + }) + f.BoolFlag(&flagset.BoolFlag{ + Name: "v5disc", + Usage: "Enables the experimental RLPx V5 (Topic Discovery) mechanism", + Value: &c.cliConfig.P2P.Discovery.V5Enabled, + }) + + // metrics + f.BoolFlag(&flagset.BoolFlag{ + Name: "metrics", + Usage: "Enable metrics collection and reporting", + Value: &c.cliConfig.Telemetry.Enabled, + }) + f.BoolFlag(&flagset.BoolFlag{ + Name: "metrics.expensive", + Usage: "Enable expensive metrics collection and reporting", + Value: &c.cliConfig.Telemetry.Expensive, + }) + f.BoolFlag(&flagset.BoolFlag{ + Name: "metrics.influxdb", + Usage: "Enable metrics export/push to an external InfluxDB database (v1)", + Value: &c.cliConfig.Telemetry.InfluxDB.V1Enabled, + }) + f.StringFlag(&flagset.StringFlag{ + Name: "metrics.influxdb.endpoint", + Usage: "InfluxDB API endpoint to report metrics to", + Value: &c.cliConfig.Telemetry.InfluxDB.Endpoint, + }) + f.StringFlag(&flagset.StringFlag{ + Name: "metrics.influxdb.database", + Usage: "InfluxDB database name to push reported metrics to", + Value: &c.cliConfig.Telemetry.InfluxDB.Database, + }) + f.StringFlag(&flagset.StringFlag{ + Name: "metrics.influxdb.username", + Usage: "Username to authorize access to the database", + Value: &c.cliConfig.Telemetry.InfluxDB.Username, + }) + f.StringFlag(&flagset.StringFlag{ + Name: "metrics.influxdb.password", + Usage: "Password to authorize access to the database", + Value: &c.cliConfig.Telemetry.InfluxDB.Password, + }) + f.MapStringFlag(&flagset.MapStringFlag{ + Name: "metrics.influxdb.tags", + Usage: "Comma-separated InfluxDB tags (key/values) attached to all measurements", + Value: &c.cliConfig.Telemetry.InfluxDB.Tags, + }) + f.StringFlag(&flagset.StringFlag{ + Name: "metrics.prometheus-addr", + Usage: "Address for Prometheus Server", + Value: &c.cliConfig.Telemetry.PrometheusAddr, + }) + f.StringFlag(&flagset.StringFlag{ + Name: "metrics.opencollector-endpoint", + Usage: "OpenCollector Endpoint (host:port)", + Value: &c.cliConfig.Telemetry.OpenCollectorEndpoint, + }) + // influx db v2 + f.BoolFlag(&flagset.BoolFlag{ + Name: "metrics.influxdbv2", + Usage: "Enable metrics export/push to an external InfluxDB v2 database", + Value: &c.cliConfig.Telemetry.InfluxDB.V2Enabled, + }) + f.StringFlag(&flagset.StringFlag{ + Name: "metrics.influxdb.token", + Usage: "Token to authorize access to the database (v2 only)", + Value: &c.cliConfig.Telemetry.InfluxDB.Token, + }) + f.StringFlag(&flagset.StringFlag{ + Name: "metrics.influxdb.bucket", + Usage: "InfluxDB bucket name to push reported metrics to (v2 only)", + Value: &c.cliConfig.Telemetry.InfluxDB.Bucket, + }) + f.StringFlag(&flagset.StringFlag{ + Name: "metrics.influxdb.organization", + Usage: "InfluxDB organization name (v2 only)", + Value: &c.cliConfig.Telemetry.InfluxDB.Organization, + }) + + // account + f.SliceStringFlag(&flagset.SliceStringFlag{ + Name: "unlock", + Usage: "Comma separated list of accounts to unlock", + Value: &c.cliConfig.Accounts.Unlock, + }) + f.StringFlag(&flagset.StringFlag{ + Name: "password", + Usage: "Password file to use for non-interactive password input", + Value: &c.cliConfig.Accounts.PasswordFile, + }) + f.BoolFlag(&flagset.BoolFlag{ + Name: "allow-insecure-unlock", + Usage: "Allow insecure account unlocking when account-related RPCs are exposed by http", + Value: &c.cliConfig.Accounts.AllowInsecureUnlock, + }) + f.BoolFlag(&flagset.BoolFlag{ + Name: "lightkdf", + Usage: "Reduce key-derivation RAM & CPU usage at some expense of KDF strength", + Value: &c.cliConfig.Accounts.UseLightweightKDF, + }) + + // grpc + f.StringFlag(&flagset.StringFlag{ + Name: "grpc.addr", + Usage: "Address and port to bind the GRPC server", + Value: &c.cliConfig.GRPC.Addr, + }) + return f +} diff --git a/command/server/pprof/pprof.go b/command/server/pprof/pprof.go new file mode 100644 index 0000000000000000000000000000000000000000..44034f3bb8ddb4ba4437ce1389775e775d241255 --- /dev/null +++ b/command/server/pprof/pprof.go @@ -0,0 +1,93 @@ +package pprof + +import ( + "bytes" + "context" + "fmt" + "runtime" + "runtime/pprof" + "runtime/trace" + "time" +) + +// Profile generates a pprof.Profile report for the given profile name. +func Profile(profile string, debug, gc int) ([]byte, map[string]string, error) { + p := pprof.Lookup(profile) + if p == nil { + return nil, nil, fmt.Errorf("profile '%s' not found", profile) + } + + if profile == "heap" && gc > 0 { + runtime.GC() + } + + var buf bytes.Buffer + if err := p.WriteTo(&buf, debug); err != nil { + return nil, nil, err + } + + headers := map[string]string{ + "X-Content-Type-Options": "nosniff", + } + if debug != 0 { + headers["Content-Type"] = "text/plain; charset=utf-8" + } else { + headers["Content-Type"] = "application/octet-stream" + headers["Content-Disposition"] = fmt.Sprintf(`attachment; filename="%s"`, profile) + } + return buf.Bytes(), headers, nil +} + +// CPUProfile generates a CPU Profile for a given duration +func CPUProfile(ctx context.Context, sec int) ([]byte, map[string]string, error) { + if sec <= 0 { + sec = 1 + } + + var buf bytes.Buffer + if err := pprof.StartCPUProfile(&buf); err != nil { + return nil, nil, err + } + + sleep(ctx, time.Duration(sec)*time.Second) + + pprof.StopCPUProfile() + + return buf.Bytes(), + map[string]string{ + "X-Content-Type-Options": "nosniff", + "Content-Type": "application/octet-stream", + "Content-Disposition": `attachment; filename="profile"`, + }, nil +} + +// Trace runs a trace profile for a given duration +func Trace(ctx context.Context, sec int) ([]byte, map[string]string, error) { + if sec <= 0 { + sec = 1 + } + + var buf bytes.Buffer + if err := trace.Start(&buf); err != nil { + return nil, nil, err + } + + sleep(ctx, time.Duration(sec)*time.Second) + + trace.Stop() + + return buf.Bytes(), + map[string]string{ + "X-Content-Type-Options": "nosniff", + "Content-Type": "application/octet-stream", + "Content-Disposition": `attachment; filename="trace"`, + }, nil +} + +func sleep(ctx context.Context, d time.Duration) { + // Sleep until duration is met or ctx is cancelled + select { + case <-time.After(d): + case <-ctx.Done(): + } +} diff --git a/command/server/proto/server.pb.go b/command/server/proto/server.pb.go new file mode 100644 index 0000000000000000000000000000000000000000..ab6c06662b9bd919fbe87fccf0f7b1314be65ff0 --- /dev/null +++ b/command/server/proto/server.pb.go @@ -0,0 +1,1068 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.25.0 +// protoc v3.12.0 +// source: command/server/proto/server.proto + +package proto + +import ( + proto "github.com/golang/protobuf/proto" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// This is a compile-time assertion that a sufficiently up-to-date version +// of the legacy proto package is being used. +const _ = proto.ProtoPackageIsVersion4 + +type PprofRequest_Type int32 + +const ( + PprofRequest_LOOKUP PprofRequest_Type = 0 + PprofRequest_CPU PprofRequest_Type = 1 + PprofRequest_TRACE PprofRequest_Type = 2 +) + +// Enum value maps for PprofRequest_Type. +var ( + PprofRequest_Type_name = map[int32]string{ + 0: "LOOKUP", + 1: "CPU", + 2: "TRACE", + } + PprofRequest_Type_value = map[string]int32{ + "LOOKUP": 0, + "CPU": 1, + "TRACE": 2, + } +) + +func (x PprofRequest_Type) Enum() *PprofRequest_Type { + p := new(PprofRequest_Type) + *p = x + return p +} + +func (x PprofRequest_Type) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (PprofRequest_Type) Descriptor() protoreflect.EnumDescriptor { + return file_command_server_proto_server_proto_enumTypes[0].Descriptor() +} + +func (PprofRequest_Type) Type() protoreflect.EnumType { + return &file_command_server_proto_server_proto_enumTypes[0] +} + +func (x PprofRequest_Type) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use PprofRequest_Type.Descriptor instead. +func (PprofRequest_Type) EnumDescriptor() ([]byte, []int) { + return file_command_server_proto_server_proto_rawDescGZIP(), []int{11, 0} +} + +type PeersAddRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Enode string `protobuf:"bytes,1,opt,name=enode,proto3" json:"enode,omitempty"` + Trusted bool `protobuf:"varint,2,opt,name=trusted,proto3" json:"trusted,omitempty"` +} + +func (x *PeersAddRequest) Reset() { + *x = PeersAddRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_command_server_proto_server_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PeersAddRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PeersAddRequest) ProtoMessage() {} + +func (x *PeersAddRequest) ProtoReflect() protoreflect.Message { + mi := &file_command_server_proto_server_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PeersAddRequest.ProtoReflect.Descriptor instead. +func (*PeersAddRequest) Descriptor() ([]byte, []int) { + return file_command_server_proto_server_proto_rawDescGZIP(), []int{0} +} + +func (x *PeersAddRequest) GetEnode() string { + if x != nil { + return x.Enode + } + return "" +} + +func (x *PeersAddRequest) GetTrusted() bool { + if x != nil { + return x.Trusted + } + return false +} + +type PeersAddResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *PeersAddResponse) Reset() { + *x = PeersAddResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_command_server_proto_server_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PeersAddResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PeersAddResponse) ProtoMessage() {} + +func (x *PeersAddResponse) ProtoReflect() protoreflect.Message { + mi := &file_command_server_proto_server_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PeersAddResponse.ProtoReflect.Descriptor instead. +func (*PeersAddResponse) Descriptor() ([]byte, []int) { + return file_command_server_proto_server_proto_rawDescGZIP(), []int{1} +} + +type PeersRemoveRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Enode string `protobuf:"bytes,1,opt,name=enode,proto3" json:"enode,omitempty"` + Trusted bool `protobuf:"varint,2,opt,name=trusted,proto3" json:"trusted,omitempty"` +} + +func (x *PeersRemoveRequest) Reset() { + *x = PeersRemoveRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_command_server_proto_server_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PeersRemoveRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PeersRemoveRequest) ProtoMessage() {} + +func (x *PeersRemoveRequest) ProtoReflect() protoreflect.Message { + mi := &file_command_server_proto_server_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PeersRemoveRequest.ProtoReflect.Descriptor instead. +func (*PeersRemoveRequest) Descriptor() ([]byte, []int) { + return file_command_server_proto_server_proto_rawDescGZIP(), []int{2} +} + +func (x *PeersRemoveRequest) GetEnode() string { + if x != nil { + return x.Enode + } + return "" +} + +func (x *PeersRemoveRequest) GetTrusted() bool { + if x != nil { + return x.Trusted + } + return false +} + +type PeersRemoveResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *PeersRemoveResponse) Reset() { + *x = PeersRemoveResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_command_server_proto_server_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PeersRemoveResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PeersRemoveResponse) ProtoMessage() {} + +func (x *PeersRemoveResponse) ProtoReflect() protoreflect.Message { + mi := &file_command_server_proto_server_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PeersRemoveResponse.ProtoReflect.Descriptor instead. +func (*PeersRemoveResponse) Descriptor() ([]byte, []int) { + return file_command_server_proto_server_proto_rawDescGZIP(), []int{3} +} + +type PeersListRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *PeersListRequest) Reset() { + *x = PeersListRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_command_server_proto_server_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PeersListRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PeersListRequest) ProtoMessage() {} + +func (x *PeersListRequest) ProtoReflect() protoreflect.Message { + mi := &file_command_server_proto_server_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PeersListRequest.ProtoReflect.Descriptor instead. +func (*PeersListRequest) Descriptor() ([]byte, []int) { + return file_command_server_proto_server_proto_rawDescGZIP(), []int{4} +} + +type PeersListResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Peers []*Peer `protobuf:"bytes,1,rep,name=peers,proto3" json:"peers,omitempty"` +} + +func (x *PeersListResponse) Reset() { + *x = PeersListResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_command_server_proto_server_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PeersListResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PeersListResponse) ProtoMessage() {} + +func (x *PeersListResponse) ProtoReflect() protoreflect.Message { + mi := &file_command_server_proto_server_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PeersListResponse.ProtoReflect.Descriptor instead. +func (*PeersListResponse) Descriptor() ([]byte, []int) { + return file_command_server_proto_server_proto_rawDescGZIP(), []int{5} +} + +func (x *PeersListResponse) GetPeers() []*Peer { + if x != nil { + return x.Peers + } + return nil +} + +type PeersStatusRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Enode string `protobuf:"bytes,1,opt,name=enode,proto3" json:"enode,omitempty"` +} + +func (x *PeersStatusRequest) Reset() { + *x = PeersStatusRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_command_server_proto_server_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PeersStatusRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PeersStatusRequest) ProtoMessage() {} + +func (x *PeersStatusRequest) ProtoReflect() protoreflect.Message { + mi := &file_command_server_proto_server_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PeersStatusRequest.ProtoReflect.Descriptor instead. +func (*PeersStatusRequest) Descriptor() ([]byte, []int) { + return file_command_server_proto_server_proto_rawDescGZIP(), []int{6} +} + +func (x *PeersStatusRequest) GetEnode() string { + if x != nil { + return x.Enode + } + return "" +} + +type PeersStatusResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Peer *Peer `protobuf:"bytes,1,opt,name=peer,proto3" json:"peer,omitempty"` +} + +func (x *PeersStatusResponse) Reset() { + *x = PeersStatusResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_command_server_proto_server_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PeersStatusResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PeersStatusResponse) ProtoMessage() {} + +func (x *PeersStatusResponse) ProtoReflect() protoreflect.Message { + mi := &file_command_server_proto_server_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PeersStatusResponse.ProtoReflect.Descriptor instead. +func (*PeersStatusResponse) Descriptor() ([]byte, []int) { + return file_command_server_proto_server_proto_rawDescGZIP(), []int{7} +} + +func (x *PeersStatusResponse) GetPeer() *Peer { + if x != nil { + return x.Peer + } + return nil +} + +type Peer struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Enode string `protobuf:"bytes,2,opt,name=enode,proto3" json:"enode,omitempty"` + Enr string `protobuf:"bytes,3,opt,name=enr,proto3" json:"enr,omitempty"` + Caps []string `protobuf:"bytes,4,rep,name=caps,proto3" json:"caps,omitempty"` + Name string `protobuf:"bytes,5,opt,name=name,proto3" json:"name,omitempty"` + Trusted bool `protobuf:"varint,6,opt,name=trusted,proto3" json:"trusted,omitempty"` + Static bool `protobuf:"varint,7,opt,name=static,proto3" json:"static,omitempty"` +} + +func (x *Peer) Reset() { + *x = Peer{} + if protoimpl.UnsafeEnabled { + mi := &file_command_server_proto_server_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Peer) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Peer) ProtoMessage() {} + +func (x *Peer) ProtoReflect() protoreflect.Message { + mi := &file_command_server_proto_server_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Peer.ProtoReflect.Descriptor instead. +func (*Peer) Descriptor() ([]byte, []int) { + return file_command_server_proto_server_proto_rawDescGZIP(), []int{8} +} + +func (x *Peer) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *Peer) GetEnode() string { + if x != nil { + return x.Enode + } + return "" +} + +func (x *Peer) GetEnr() string { + if x != nil { + return x.Enr + } + return "" +} + +func (x *Peer) GetCaps() []string { + if x != nil { + return x.Caps + } + return nil +} + +func (x *Peer) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Peer) GetTrusted() bool { + if x != nil { + return x.Trusted + } + return false +} + +func (x *Peer) GetStatic() bool { + if x != nil { + return x.Static + } + return false +} + +type ChainSetHeadRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Number uint64 `protobuf:"varint,1,opt,name=number,proto3" json:"number,omitempty"` +} + +func (x *ChainSetHeadRequest) Reset() { + *x = ChainSetHeadRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_command_server_proto_server_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ChainSetHeadRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ChainSetHeadRequest) ProtoMessage() {} + +func (x *ChainSetHeadRequest) ProtoReflect() protoreflect.Message { + mi := &file_command_server_proto_server_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ChainSetHeadRequest.ProtoReflect.Descriptor instead. +func (*ChainSetHeadRequest) Descriptor() ([]byte, []int) { + return file_command_server_proto_server_proto_rawDescGZIP(), []int{9} +} + +func (x *ChainSetHeadRequest) GetNumber() uint64 { + if x != nil { + return x.Number + } + return 0 +} + +type ChainSetHeadResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *ChainSetHeadResponse) Reset() { + *x = ChainSetHeadResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_command_server_proto_server_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ChainSetHeadResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ChainSetHeadResponse) ProtoMessage() {} + +func (x *ChainSetHeadResponse) ProtoReflect() protoreflect.Message { + mi := &file_command_server_proto_server_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ChainSetHeadResponse.ProtoReflect.Descriptor instead. +func (*ChainSetHeadResponse) Descriptor() ([]byte, []int) { + return file_command_server_proto_server_proto_rawDescGZIP(), []int{10} +} + +type PprofRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Type PprofRequest_Type `protobuf:"varint,1,opt,name=type,proto3,enum=proto.PprofRequest_Type" json:"type,omitempty"` + Profile string `protobuf:"bytes,2,opt,name=profile,proto3" json:"profile,omitempty"` + Seconds int64 `protobuf:"varint,3,opt,name=seconds,proto3" json:"seconds,omitempty"` +} + +func (x *PprofRequest) Reset() { + *x = PprofRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_command_server_proto_server_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PprofRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PprofRequest) ProtoMessage() {} + +func (x *PprofRequest) ProtoReflect() protoreflect.Message { + mi := &file_command_server_proto_server_proto_msgTypes[11] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PprofRequest.ProtoReflect.Descriptor instead. +func (*PprofRequest) Descriptor() ([]byte, []int) { + return file_command_server_proto_server_proto_rawDescGZIP(), []int{11} +} + +func (x *PprofRequest) GetType() PprofRequest_Type { + if x != nil { + return x.Type + } + return PprofRequest_LOOKUP +} + +func (x *PprofRequest) GetProfile() string { + if x != nil { + return x.Profile + } + return "" +} + +func (x *PprofRequest) GetSeconds() int64 { + if x != nil { + return x.Seconds + } + return 0 +} + +type PprofResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Payload string `protobuf:"bytes,1,opt,name=payload,proto3" json:"payload,omitempty"` + Headers map[string]string `protobuf:"bytes,2,rep,name=headers,proto3" json:"headers,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *PprofResponse) Reset() { + *x = PprofResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_command_server_proto_server_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PprofResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PprofResponse) ProtoMessage() {} + +func (x *PprofResponse) ProtoReflect() protoreflect.Message { + mi := &file_command_server_proto_server_proto_msgTypes[12] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PprofResponse.ProtoReflect.Descriptor instead. +func (*PprofResponse) Descriptor() ([]byte, []int) { + return file_command_server_proto_server_proto_rawDescGZIP(), []int{12} +} + +func (x *PprofResponse) GetPayload() string { + if x != nil { + return x.Payload + } + return "" +} + +func (x *PprofResponse) GetHeaders() map[string]string { + if x != nil { + return x.Headers + } + return nil +} + +var File_command_server_proto_server_proto protoreflect.FileDescriptor + +var file_command_server_proto_server_proto_rawDesc = []byte{ + 0x0a, 0x21, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x12, 0x05, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x41, 0x0a, 0x0f, 0x50, 0x65, + 0x65, 0x72, 0x73, 0x41, 0x64, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, + 0x05, 0x65, 0x6e, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6e, + 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x74, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x22, 0x12, 0x0a, + 0x10, 0x50, 0x65, 0x65, 0x72, 0x73, 0x41, 0x64, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x44, 0x0a, 0x12, 0x50, 0x65, 0x65, 0x72, 0x73, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6e, 0x6f, 0x64, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6e, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, + 0x07, 0x74, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, + 0x74, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x22, 0x15, 0x0a, 0x13, 0x50, 0x65, 0x65, 0x72, 0x73, + 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x12, + 0x0a, 0x10, 0x50, 0x65, 0x65, 0x72, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x22, 0x36, 0x0a, 0x11, 0x50, 0x65, 0x65, 0x72, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x21, 0x0a, 0x05, 0x70, 0x65, 0x65, 0x72, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, + 0x65, 0x65, 0x72, 0x52, 0x05, 0x70, 0x65, 0x65, 0x72, 0x73, 0x22, 0x2a, 0x0a, 0x12, 0x50, 0x65, + 0x65, 0x72, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6e, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x65, 0x6e, 0x6f, 0x64, 0x65, 0x22, 0x36, 0x0a, 0x13, 0x50, 0x65, 0x65, 0x72, 0x73, 0x53, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, + 0x04, 0x70, 0x65, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x52, 0x04, 0x70, 0x65, 0x65, 0x72, 0x22, 0x98, + 0x01, 0x0a, 0x04, 0x50, 0x65, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6e, 0x6f, 0x64, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6e, 0x6f, 0x64, 0x65, 0x12, 0x10, 0x0a, + 0x03, 0x65, 0x6e, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x65, 0x6e, 0x72, 0x12, + 0x12, 0x0a, 0x04, 0x63, 0x61, 0x70, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x63, + 0x61, 0x70, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x72, 0x75, 0x73, 0x74, + 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x74, 0x72, 0x75, 0x73, 0x74, 0x65, + 0x64, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x18, 0x07, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x22, 0x2d, 0x0a, 0x13, 0x43, 0x68, 0x61, + 0x69, 0x6e, 0x53, 0x65, 0x74, 0x48, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22, 0x16, 0x0a, 0x14, 0x43, 0x68, 0x61, 0x69, + 0x6e, 0x53, 0x65, 0x74, 0x48, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x98, 0x01, 0x0a, 0x0c, 0x50, 0x70, 0x72, 0x6f, 0x66, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x2c, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x70, 0x72, 0x6f, 0x66, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, + 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x07, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, 0x63, + 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x73, 0x65, 0x63, 0x6f, + 0x6e, 0x64, 0x73, 0x22, 0x26, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0a, 0x0a, 0x06, 0x4c, + 0x4f, 0x4f, 0x4b, 0x55, 0x50, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x43, 0x50, 0x55, 0x10, 0x01, + 0x12, 0x09, 0x0a, 0x05, 0x54, 0x52, 0x41, 0x43, 0x45, 0x10, 0x02, 0x22, 0xa2, 0x01, 0x0a, 0x0d, + 0x50, 0x70, 0x72, 0x6f, 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, + 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, + 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x3b, 0x0a, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, + 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x50, 0x70, 0x72, 0x6f, 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x48, + 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x68, 0x65, 0x61, + 0x64, 0x65, 0x72, 0x73, 0x1a, 0x3a, 0x0a, 0x0c, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, + 0x32, 0x8b, 0x03, 0x0a, 0x03, 0x42, 0x6f, 0x72, 0x12, 0x32, 0x0a, 0x05, 0x50, 0x70, 0x72, 0x6f, + 0x66, 0x12, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x70, 0x72, 0x6f, 0x66, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, + 0x70, 0x72, 0x6f, 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x08, + 0x50, 0x65, 0x65, 0x72, 0x73, 0x41, 0x64, 0x64, 0x12, 0x16, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x50, 0x65, 0x65, 0x72, 0x73, 0x41, 0x64, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x73, 0x41, 0x64, + 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x44, 0x0a, 0x0b, 0x50, 0x65, 0x65, + 0x72, 0x73, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x12, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x50, 0x65, 0x65, 0x72, 0x73, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x65, 0x65, 0x72, + 0x73, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x3e, 0x0a, 0x09, 0x50, 0x65, 0x65, 0x72, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x17, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x65, + 0x65, 0x72, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x44, 0x0a, 0x0b, 0x50, 0x65, 0x65, 0x72, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x19, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x73, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x47, 0x0a, 0x0c, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x53, 0x65, + 0x74, 0x48, 0x65, 0x61, 0x64, 0x12, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x68, + 0x61, 0x69, 0x6e, 0x53, 0x65, 0x74, 0x48, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x53, + 0x65, 0x74, 0x48, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x17, + 0x5a, 0x15, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_command_server_proto_server_proto_rawDescOnce sync.Once + file_command_server_proto_server_proto_rawDescData = file_command_server_proto_server_proto_rawDesc +) + +func file_command_server_proto_server_proto_rawDescGZIP() []byte { + file_command_server_proto_server_proto_rawDescOnce.Do(func() { + file_command_server_proto_server_proto_rawDescData = protoimpl.X.CompressGZIP(file_command_server_proto_server_proto_rawDescData) + }) + return file_command_server_proto_server_proto_rawDescData +} + +var file_command_server_proto_server_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_command_server_proto_server_proto_msgTypes = make([]protoimpl.MessageInfo, 14) +var file_command_server_proto_server_proto_goTypes = []interface{}{ + (PprofRequest_Type)(0), // 0: proto.PprofRequest.Type + (*PeersAddRequest)(nil), // 1: proto.PeersAddRequest + (*PeersAddResponse)(nil), // 2: proto.PeersAddResponse + (*PeersRemoveRequest)(nil), // 3: proto.PeersRemoveRequest + (*PeersRemoveResponse)(nil), // 4: proto.PeersRemoveResponse + (*PeersListRequest)(nil), // 5: proto.PeersListRequest + (*PeersListResponse)(nil), // 6: proto.PeersListResponse + (*PeersStatusRequest)(nil), // 7: proto.PeersStatusRequest + (*PeersStatusResponse)(nil), // 8: proto.PeersStatusResponse + (*Peer)(nil), // 9: proto.Peer + (*ChainSetHeadRequest)(nil), // 10: proto.ChainSetHeadRequest + (*ChainSetHeadResponse)(nil), // 11: proto.ChainSetHeadResponse + (*PprofRequest)(nil), // 12: proto.PprofRequest + (*PprofResponse)(nil), // 13: proto.PprofResponse + nil, // 14: proto.PprofResponse.HeadersEntry +} +var file_command_server_proto_server_proto_depIdxs = []int32{ + 9, // 0: proto.PeersListResponse.peers:type_name -> proto.Peer + 9, // 1: proto.PeersStatusResponse.peer:type_name -> proto.Peer + 0, // 2: proto.PprofRequest.type:type_name -> proto.PprofRequest.Type + 14, // 3: proto.PprofResponse.headers:type_name -> proto.PprofResponse.HeadersEntry + 12, // 4: proto.Bor.Pprof:input_type -> proto.PprofRequest + 1, // 5: proto.Bor.PeersAdd:input_type -> proto.PeersAddRequest + 3, // 6: proto.Bor.PeersRemove:input_type -> proto.PeersRemoveRequest + 5, // 7: proto.Bor.PeersList:input_type -> proto.PeersListRequest + 7, // 8: proto.Bor.PeersStatus:input_type -> proto.PeersStatusRequest + 10, // 9: proto.Bor.ChainSetHead:input_type -> proto.ChainSetHeadRequest + 13, // 10: proto.Bor.Pprof:output_type -> proto.PprofResponse + 2, // 11: proto.Bor.PeersAdd:output_type -> proto.PeersAddResponse + 4, // 12: proto.Bor.PeersRemove:output_type -> proto.PeersRemoveResponse + 6, // 13: proto.Bor.PeersList:output_type -> proto.PeersListResponse + 8, // 14: proto.Bor.PeersStatus:output_type -> proto.PeersStatusResponse + 11, // 15: proto.Bor.ChainSetHead:output_type -> proto.ChainSetHeadResponse + 10, // [10:16] is the sub-list for method output_type + 4, // [4:10] is the sub-list for method input_type + 4, // [4:4] is the sub-list for extension type_name + 4, // [4:4] is the sub-list for extension extendee + 0, // [0:4] is the sub-list for field type_name +} + +func init() { file_command_server_proto_server_proto_init() } +func file_command_server_proto_server_proto_init() { + if File_command_server_proto_server_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_command_server_proto_server_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PeersAddRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_command_server_proto_server_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PeersAddResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_command_server_proto_server_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PeersRemoveRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_command_server_proto_server_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PeersRemoveResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_command_server_proto_server_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PeersListRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_command_server_proto_server_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PeersListResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_command_server_proto_server_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PeersStatusRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_command_server_proto_server_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PeersStatusResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_command_server_proto_server_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Peer); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_command_server_proto_server_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ChainSetHeadRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_command_server_proto_server_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ChainSetHeadResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_command_server_proto_server_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PprofRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_command_server_proto_server_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PprofResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_command_server_proto_server_proto_rawDesc, + NumEnums: 1, + NumMessages: 14, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_command_server_proto_server_proto_goTypes, + DependencyIndexes: file_command_server_proto_server_proto_depIdxs, + EnumInfos: file_command_server_proto_server_proto_enumTypes, + MessageInfos: file_command_server_proto_server_proto_msgTypes, + }.Build() + File_command_server_proto_server_proto = out.File + file_command_server_proto_server_proto_rawDesc = nil + file_command_server_proto_server_proto_goTypes = nil + file_command_server_proto_server_proto_depIdxs = nil +} diff --git a/command/server/proto/server.proto b/command/server/proto/server.proto new file mode 100644 index 0000000000000000000000000000000000000000..535aa3f3695272853ec29afae5ad505838f9fc81 --- /dev/null +++ b/command/server/proto/server.proto @@ -0,0 +1,87 @@ +syntax = "proto3"; + +package proto; + +option go_package = "/command/server/proto"; + +service Bor { + rpc Pprof(PprofRequest) returns (PprofResponse); + + rpc PeersAdd(PeersAddRequest) returns (PeersAddResponse); + + rpc PeersRemove(PeersRemoveRequest) returns (PeersRemoveResponse); + + rpc PeersList(PeersListRequest) returns (PeersListResponse); + + rpc PeersStatus(PeersStatusRequest) returns (PeersStatusResponse); + + rpc ChainSetHead(ChainSetHeadRequest) returns (ChainSetHeadResponse); +} + + +message PeersAddRequest { + string enode = 1; + bool trusted = 2; +} + +message PeersAddResponse { +} + +message PeersRemoveRequest { + string enode = 1; + bool trusted = 2; +} + +message PeersRemoveResponse { +} + +message PeersListRequest { +} + +message PeersListResponse { + repeated Peer peers = 1; +} + +message PeersStatusRequest { + string enode = 1; +} + +message PeersStatusResponse { + Peer peer = 1; +} + +message Peer { + string id = 1; + string enode = 2; + string enr = 3; + repeated string caps = 4; + string name = 5; + bool trusted = 6; + bool static = 7; +} + +message ChainSetHeadRequest { + uint64 number = 1; +} + +message ChainSetHeadResponse { +} + +message PprofRequest { + Type type = 1; + + string profile = 2; + + int64 seconds = 3; + + enum Type { + LOOKUP = 0; + CPU = 1; + TRACE = 2; + } +} + +message PprofResponse { + string payload = 1; + map<string, string> headers = 2; +} diff --git a/command/server/proto/server_grpc.pb.go b/command/server/proto/server_grpc.pb.go new file mode 100644 index 0000000000000000000000000000000000000000..369419b66fc2bbbdf8051a6c5faa5230adf561f3 --- /dev/null +++ b/command/server/proto/server_grpc.pb.go @@ -0,0 +1,281 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. + +package proto + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// BorClient is the client API for Bor service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type BorClient interface { + Pprof(ctx context.Context, in *PprofRequest, opts ...grpc.CallOption) (*PprofResponse, error) + PeersAdd(ctx context.Context, in *PeersAddRequest, opts ...grpc.CallOption) (*PeersAddResponse, error) + PeersRemove(ctx context.Context, in *PeersRemoveRequest, opts ...grpc.CallOption) (*PeersRemoveResponse, error) + PeersList(ctx context.Context, in *PeersListRequest, opts ...grpc.CallOption) (*PeersListResponse, error) + PeersStatus(ctx context.Context, in *PeersStatusRequest, opts ...grpc.CallOption) (*PeersStatusResponse, error) + ChainSetHead(ctx context.Context, in *ChainSetHeadRequest, opts ...grpc.CallOption) (*ChainSetHeadResponse, error) +} + +type borClient struct { + cc grpc.ClientConnInterface +} + +func NewBorClient(cc grpc.ClientConnInterface) BorClient { + return &borClient{cc} +} + +func (c *borClient) Pprof(ctx context.Context, in *PprofRequest, opts ...grpc.CallOption) (*PprofResponse, error) { + out := new(PprofResponse) + err := c.cc.Invoke(ctx, "/proto.Bor/Pprof", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *borClient) PeersAdd(ctx context.Context, in *PeersAddRequest, opts ...grpc.CallOption) (*PeersAddResponse, error) { + out := new(PeersAddResponse) + err := c.cc.Invoke(ctx, "/proto.Bor/PeersAdd", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *borClient) PeersRemove(ctx context.Context, in *PeersRemoveRequest, opts ...grpc.CallOption) (*PeersRemoveResponse, error) { + out := new(PeersRemoveResponse) + err := c.cc.Invoke(ctx, "/proto.Bor/PeersRemove", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *borClient) PeersList(ctx context.Context, in *PeersListRequest, opts ...grpc.CallOption) (*PeersListResponse, error) { + out := new(PeersListResponse) + err := c.cc.Invoke(ctx, "/proto.Bor/PeersList", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *borClient) PeersStatus(ctx context.Context, in *PeersStatusRequest, opts ...grpc.CallOption) (*PeersStatusResponse, error) { + out := new(PeersStatusResponse) + err := c.cc.Invoke(ctx, "/proto.Bor/PeersStatus", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *borClient) ChainSetHead(ctx context.Context, in *ChainSetHeadRequest, opts ...grpc.CallOption) (*ChainSetHeadResponse, error) { + out := new(ChainSetHeadResponse) + err := c.cc.Invoke(ctx, "/proto.Bor/ChainSetHead", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// BorServer is the server API for Bor service. +// All implementations must embed UnimplementedBorServer +// for forward compatibility +type BorServer interface { + Pprof(context.Context, *PprofRequest) (*PprofResponse, error) + PeersAdd(context.Context, *PeersAddRequest) (*PeersAddResponse, error) + PeersRemove(context.Context, *PeersRemoveRequest) (*PeersRemoveResponse, error) + PeersList(context.Context, *PeersListRequest) (*PeersListResponse, error) + PeersStatus(context.Context, *PeersStatusRequest) (*PeersStatusResponse, error) + ChainSetHead(context.Context, *ChainSetHeadRequest) (*ChainSetHeadResponse, error) + mustEmbedUnimplementedBorServer() +} + +// UnimplementedBorServer must be embedded to have forward compatible implementations. +type UnimplementedBorServer struct { +} + +func (UnimplementedBorServer) Pprof(context.Context, *PprofRequest) (*PprofResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Pprof not implemented") +} +func (UnimplementedBorServer) PeersAdd(context.Context, *PeersAddRequest) (*PeersAddResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method PeersAdd not implemented") +} +func (UnimplementedBorServer) PeersRemove(context.Context, *PeersRemoveRequest) (*PeersRemoveResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method PeersRemove not implemented") +} +func (UnimplementedBorServer) PeersList(context.Context, *PeersListRequest) (*PeersListResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method PeersList not implemented") +} +func (UnimplementedBorServer) PeersStatus(context.Context, *PeersStatusRequest) (*PeersStatusResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method PeersStatus not implemented") +} +func (UnimplementedBorServer) ChainSetHead(context.Context, *ChainSetHeadRequest) (*ChainSetHeadResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ChainSetHead not implemented") +} +func (UnimplementedBorServer) mustEmbedUnimplementedBorServer() {} + +// UnsafeBorServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to BorServer will +// result in compilation errors. +type UnsafeBorServer interface { + mustEmbedUnimplementedBorServer() +} + +func RegisterBorServer(s grpc.ServiceRegistrar, srv BorServer) { + s.RegisterService(&Bor_ServiceDesc, srv) +} + +func _Bor_Pprof_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PprofRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BorServer).Pprof(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/proto.Bor/Pprof", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BorServer).Pprof(ctx, req.(*PprofRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Bor_PeersAdd_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PeersAddRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BorServer).PeersAdd(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/proto.Bor/PeersAdd", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BorServer).PeersAdd(ctx, req.(*PeersAddRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Bor_PeersRemove_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PeersRemoveRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BorServer).PeersRemove(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/proto.Bor/PeersRemove", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BorServer).PeersRemove(ctx, req.(*PeersRemoveRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Bor_PeersList_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PeersListRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BorServer).PeersList(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/proto.Bor/PeersList", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BorServer).PeersList(ctx, req.(*PeersListRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Bor_PeersStatus_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PeersStatusRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BorServer).PeersStatus(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/proto.Bor/PeersStatus", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BorServer).PeersStatus(ctx, req.(*PeersStatusRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Bor_ChainSetHead_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ChainSetHeadRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BorServer).ChainSetHead(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/proto.Bor/ChainSetHead", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BorServer).ChainSetHead(ctx, req.(*ChainSetHeadRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// Bor_ServiceDesc is the grpc.ServiceDesc for Bor service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var Bor_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "proto.Bor", + HandlerType: (*BorServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Pprof", + Handler: _Bor_Pprof_Handler, + }, + { + MethodName: "PeersAdd", + Handler: _Bor_PeersAdd_Handler, + }, + { + MethodName: "PeersRemove", + Handler: _Bor_PeersRemove_Handler, + }, + { + MethodName: "PeersList", + Handler: _Bor_PeersList_Handler, + }, + { + MethodName: "PeersStatus", + Handler: _Bor_PeersStatus_Handler, + }, + { + MethodName: "ChainSetHead", + Handler: _Bor_ChainSetHead_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "command/server/proto/server.proto", +} diff --git a/command/server/server.go b/command/server/server.go new file mode 100644 index 0000000000000000000000000000000000000000..bab4673214f668d1da9f209416c4c85bdae13df4 --- /dev/null +++ b/command/server/server.go @@ -0,0 +1,282 @@ +package server + +import ( + "context" + "fmt" + "io" + "net" + "net/http" + "os" + "strings" + "time" + + "github.com/ethereum/go-ethereum/accounts/keystore" + "github.com/ethereum/go-ethereum/command/server/proto" + "github.com/ethereum/go-ethereum/eth" + "github.com/ethereum/go-ethereum/eth/tracers" + "github.com/ethereum/go-ethereum/ethstats" + "github.com/ethereum/go-ethereum/graphql" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/metrics" + "github.com/ethereum/go-ethereum/metrics/influxdb" + "github.com/ethereum/go-ethereum/metrics/prometheus" + "github.com/ethereum/go-ethereum/node" + "github.com/mattn/go-colorable" + "github.com/mattn/go-isatty" + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc" + "go.opentelemetry.io/otel/propagation" + "go.opentelemetry.io/otel/sdk/resource" + sdktrace "go.opentelemetry.io/otel/sdk/trace" + semconv "go.opentelemetry.io/otel/semconv/v1.4.0" + "google.golang.org/grpc" +) + +type Server struct { + proto.UnimplementedBorServer + node *node.Node + backend *eth.Ethereum + grpcServer *grpc.Server + tracer *sdktrace.TracerProvider +} + +func NewServer(config *Config) (*Server, error) { + srv := &Server{} + + // start the logger + setupLogger(config.LogLevel) + + if err := srv.setupGRPCServer(config.GRPC.Addr); err != nil { + return nil, err + } + + // load the chain genesis + if err := config.loadChain(); err != nil { + return nil, err + } + + // create the node/stack + nodeCfg, err := config.buildNode() + if err != nil { + return nil, err + } + stack, err := node.New(nodeCfg) + if err != nil { + return nil, err + } + srv.node = stack + + // register the ethereum backend + ethCfg, err := config.buildEth() + if err != nil { + return nil, err + } + backend, err := eth.New(stack, ethCfg) + if err != nil { + return nil, err + } + srv.backend = backend + + // debug tracing is enabled by default + stack.RegisterAPIs(tracers.APIs(backend.APIBackend)) + + // graphql is started from another place + if config.JsonRPC.Graphql.Enabled { + if err := graphql.New(stack, backend.APIBackend, config.JsonRPC.Cors, config.JsonRPC.Modules); err != nil { + return nil, fmt.Errorf("failed to register the GraphQL service: %v", err) + } + } + + // register ethash service + if config.Ethstats != "" { + if err := ethstats.New(stack, backend.APIBackend, backend.Engine(), config.Ethstats); err != nil { + return nil, err + } + } + + // setup account manager (only keystore) + { + keydir := stack.KeyStoreDir() + n, p := keystore.StandardScryptN, keystore.StandardScryptP + if config.Accounts.UseLightweightKDF { + n, p = keystore.LightScryptN, keystore.LightScryptP + } + stack.AccountManager().AddBackend(keystore.NewKeyStore(keydir, n, p)) + } + + // sealing (if enabled) + if config.Sealer.Enabled { + if err := backend.StartMining(1); err != nil { + return nil, err + } + } + + if err := srv.setupMetrics(config.Telemetry, config.Name); err != nil { + return nil, err + } + + // start the node + if err := srv.node.Start(); err != nil { + return nil, err + } + return srv, nil +} + +func (s *Server) Stop() { + s.node.Close() + + // shutdown the tracer + if s.tracer != nil { + if err := s.tracer.Shutdown(context.Background()); err != nil { + log.Error("Failed to shutdown open telemetry tracer") + } + } +} + +func (s *Server) setupMetrics(config *TelemetryConfig, serviceName string) error { + metrics.Enabled = config.Enabled + metrics.EnabledExpensive = config.Expensive + + if !metrics.Enabled { + // metrics are disabled, do not set up any sink + return nil + } + + log.Info("Enabling metrics collection") + + // influxdb + if v1Enabled, v2Enabled := config.InfluxDB.V1Enabled, config.InfluxDB.V2Enabled; v1Enabled || v2Enabled { + if v1Enabled && v2Enabled { + return fmt.Errorf("both influx v1 and influx v2 cannot be enabled") + } + + cfg := config.InfluxDB + tags := cfg.Tags + endpoint := cfg.Endpoint + + if v1Enabled { + log.Info("Enabling metrics export to InfluxDB (v1)") + go influxdb.InfluxDBWithTags(metrics.DefaultRegistry, 10*time.Second, endpoint, cfg.Database, cfg.Username, cfg.Password, "geth.", tags) + } + if v2Enabled { + log.Info("Enabling metrics export to InfluxDB (v2)") + go influxdb.InfluxDBV2WithTags(metrics.DefaultRegistry, 10*time.Second, endpoint, cfg.Token, cfg.Bucket, cfg.Organization, "geth.", tags) + } + } + + // Start system runtime metrics collection + go metrics.CollectProcessMetrics(3 * time.Second) + + if config.PrometheusAddr != "" { + + prometheusMux := http.NewServeMux() + + prometheusMux.HandleFunc("/metrics", func(w http.ResponseWriter, r *http.Request) { + prometheus.Handler(metrics.DefaultRegistry) + }) + + promServer := &http.Server{ + Addr: config.PrometheusAddr, + Handler: prometheusMux, + } + + go func() { + if err := promServer.ListenAndServe(); err != nil { + log.Error("Failure in running Prometheus server", "err", err) + } + }() + + } + + if config.OpenCollectorEndpoint != "" { + // setup open collector tracer + ctx := context.Background() + + res, err := resource.New(ctx, + resource.WithAttributes( + // the service name used to display traces in backends + semconv.ServiceNameKey.String(serviceName), + ), + ) + if err != nil { + return fmt.Errorf("failed to create open telemetry resource for service: %v", err) + } + + // Set up a trace exporter + traceExporter, err := otlptracegrpc.New( + ctx, + otlptracegrpc.WithInsecure(), + otlptracegrpc.WithEndpoint(config.OpenCollectorEndpoint), + ) + if err != nil { + return fmt.Errorf("failed to create open telemetry tracer exporter for service: %v", err) + } + + // Register the trace exporter with a TracerProvider, using a batch + // span processor to aggregate spans before export. + bsp := sdktrace.NewBatchSpanProcessor(traceExporter) + tracerProvider := sdktrace.NewTracerProvider( + sdktrace.WithSampler(sdktrace.AlwaysSample()), + sdktrace.WithResource(res), + sdktrace.WithSpanProcessor(bsp), + ) + otel.SetTracerProvider(tracerProvider) + + // set global propagator to tracecontext (the default is no-op). + otel.SetTextMapPropagator(propagation.TraceContext{}) + + // set the tracer + s.tracer = tracerProvider + } + + return nil +} + +func (s *Server) setupGRPCServer(addr string) error { + s.grpcServer = grpc.NewServer(s.withLoggingUnaryInterceptor()) + proto.RegisterBorServer(s.grpcServer, s) + + lis, err := net.Listen("tcp", addr) + if err != nil { + return err + } + + go func() { + if err := s.grpcServer.Serve(lis); err != nil { + log.Error("failed to serve grpc server", "err", err) + } + }() + + log.Info("GRPC Server started", "addr", addr) + return nil +} + +func (s *Server) withLoggingUnaryInterceptor() grpc.ServerOption { + return grpc.UnaryInterceptor(s.loggingServerInterceptor) +} + +func (s *Server) loggingServerInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { + start := time.Now() + h, err := handler(ctx, req) + log.Trace("Request", "method", info.FullMethod, "duration", time.Since(start), "error", err) + return h, err +} + +func setupLogger(logLevel string) { + output := io.Writer(os.Stderr) + usecolor := (isatty.IsTerminal(os.Stderr.Fd()) || isatty.IsCygwinTerminal(os.Stderr.Fd())) && os.Getenv("TERM") != "dumb" + if usecolor { + output = colorable.NewColorableStderr() + } + ostream := log.StreamHandler(output, log.TerminalFormat(usecolor)) + glogger := log.NewGlogHandler(ostream) + + // logging + lvl, err := log.LvlFromString(strings.ToLower(logLevel)) + if err == nil { + glogger.Verbosity(lvl) + } else { + glogger.Verbosity(log.LvlInfo) + } + log.Root().SetHandler(glogger) +} diff --git a/command/server/service.go b/command/server/service.go new file mode 100644 index 0000000000000000000000000000000000000000..0c6c23b6bf51d5a235a39ccde66c8c5e250e9829 --- /dev/null +++ b/command/server/service.go @@ -0,0 +1,109 @@ +package server + +import ( + "context" + "encoding/hex" + "fmt" + "strings" + + "github.com/ethereum/go-ethereum/command/server/pprof" + "github.com/ethereum/go-ethereum/command/server/proto" + "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/p2p/enode" +) + +func (s *Server) Pprof(ctx context.Context, req *proto.PprofRequest) (*proto.PprofResponse, error) { + var payload []byte + var headers map[string]string + var err error + + switch req.Type { + case proto.PprofRequest_CPU: + payload, headers, err = pprof.CPUProfile(ctx, int(req.Seconds)) + case proto.PprofRequest_TRACE: + payload, headers, err = pprof.Trace(ctx, int(req.Seconds)) + case proto.PprofRequest_LOOKUP: + payload, headers, err = pprof.Profile(req.Profile, 0, 0) + } + if err != nil { + return nil, err + } + + resp := &proto.PprofResponse{ + Payload: hex.EncodeToString(payload), + Headers: headers, + } + return resp, nil +} + +func (s *Server) PeersAdd(ctx context.Context, req *proto.PeersAddRequest) (*proto.PeersAddResponse, error) { + node, err := enode.Parse(enode.ValidSchemes, req.Enode) + if err != nil { + return nil, fmt.Errorf("invalid enode: %v", err) + } + srv := s.node.Server() + if req.Trusted { + srv.AddTrustedPeer(node) + } else { + srv.AddPeer(node) + } + return &proto.PeersAddResponse{}, nil +} + +func (s *Server) PeersRemove(ctx context.Context, req *proto.PeersRemoveRequest) (*proto.PeersRemoveResponse, error) { + node, err := enode.Parse(enode.ValidSchemes, req.Enode) + if err != nil { + return nil, fmt.Errorf("invalid enode: %v", err) + } + srv := s.node.Server() + if req.Trusted { + srv.RemoveTrustedPeer(node) + } else { + srv.RemovePeer(node) + } + return &proto.PeersRemoveResponse{}, nil +} + +func (s *Server) PeersList(ctx context.Context, req *proto.PeersListRequest) (*proto.PeersListResponse, error) { + resp := &proto.PeersListResponse{} + + peers := s.node.Server().PeersInfo() + for _, p := range peers { + resp.Peers = append(resp.Peers, peerInfoToPeer(p)) + } + return resp, nil +} + +func (s *Server) PeersStatus(ctx context.Context, req *proto.PeersStatusRequest) (*proto.PeersStatusResponse, error) { + var peerInfo *p2p.PeerInfo + for _, p := range s.node.Server().PeersInfo() { + if strings.HasPrefix(p.ID, req.Enode) { + if peerInfo != nil { + return nil, fmt.Errorf("more than one peer with the same prefix") + } + peerInfo = p + } + } + resp := &proto.PeersStatusResponse{} + if peerInfo != nil { + resp.Peer = peerInfoToPeer(peerInfo) + } + return resp, nil +} + +func peerInfoToPeer(info *p2p.PeerInfo) *proto.Peer { + return &proto.Peer{ + Id: info.ID, + Enode: info.Enode, + Enr: info.ENR, + Caps: info.Caps, + Name: info.Name, + Trusted: info.Network.Trusted, + Static: info.Network.Static, + } +} + +func (s *Server) ChainSetHead(ctx context.Context, req *proto.ChainSetHeadRequest) (*proto.ChainSetHeadResponse, error) { + s.backend.APIBackend.SetHead(req.Number) + return &proto.ChainSetHeadResponse{}, nil +} diff --git a/command/server/testdata/simple.hcl b/command/server/testdata/simple.hcl new file mode 100644 index 0000000000000000000000000000000000000000..e276960e6d4d0b332cceb7bc0e49b1d821ffd435 --- /dev/null +++ b/command/server/testdata/simple.hcl @@ -0,0 +1,17 @@ +data-dir = "./data" + +whitelist = { + a = "b" +} + +p2p { + max-peers = 30 +} + +txpool { + lifetime = "1s" +} + +gpo { + max-price = "100" +} diff --git a/command/server/testdata/simple.json b/command/server/testdata/simple.json new file mode 100644 index 0000000000000000000000000000000000000000..277f05d1059ebd1a7987e0e40c4db986bf5dbd6b --- /dev/null +++ b/command/server/testdata/simple.json @@ -0,0 +1,15 @@ +{ + "data-dir": "./data", + "whitelist": { + "a": "b" + }, + "p2p": { + "max-peers": 30 + }, + "txpool": { + "lifetime": "1s" + }, + "gpo": { + "max-price": "100" + } +} \ No newline at end of file diff --git a/command/version.go b/command/version.go new file mode 100644 index 0000000000000000000000000000000000000000..5483ea5402a9ed9d1b648e02c2630fbe3264126c --- /dev/null +++ b/command/version.go @@ -0,0 +1,30 @@ +package main + +import ( + "github.com/ethereum/go-ethereum/params" + "github.com/mitchellh/cli" +) + +// VersionCommand is the command to show the version of the agent +type VersionCommand struct { + UI cli.Ui +} + +// Help implements the cli.Command interface +func (c *VersionCommand) Help() string { + return `Usage: bor version + + Display the Bor version` +} + +// Synopsis implements the cli.Command interface +func (c *VersionCommand) Synopsis() string { + return "Display the Bor version" +} + +// Run implements the cli.Command interface +func (c *VersionCommand) Run(args []string) int { + c.UI.Output(params.VersionWithMeta) + + return 0 +} diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000000000000000000000000000000000000..b5d7993d2c49031785e3038b22db95367e30bb6a --- /dev/null +++ b/docs/README.md @@ -0,0 +1,36 @@ + +# Documentation + +- [Command-line-interface](./cli) + +- [Configuration file](./config.md) + +## Deprecation notes + +- The new entrypoint to run the Bor client is ```server```. + +``` +$ bor server +``` + +- Toml files to configure nodes are being deprecated. Currently, we only allow for static and trusted nodes to be configured using toml files. + +``` +$ bor server --config ./legacy.toml +``` + +- Modules, vhost and Cors configuration are common for all jsonrpc endpoints. + +Before: + +``` +$ bor --http --http.modules "eth,web" --ws --ws.modules "eth,web" +``` + +Now: + +``` +$ bor server --http --ws --jsonrpc.modules "eth,web" +``` + +- ```Admin```, ```Personal``` and account related endpoints in ```Eth``` are being removed from the JsonRPC interface. Some of this functionality will be moved to the new GRPC server for operational tasks. diff --git a/docs/cli/README.md b/docs/cli/README.md new file mode 100644 index 0000000000000000000000000000000000000000..c82bbbe047fa8f287c55ca5842090daa4c1aca7f --- /dev/null +++ b/docs/cli/README.md @@ -0,0 +1,18 @@ + +# Command line interface + +## Commands + +- [```server```](./server.md) + +- [```debug```](./debug.md) + +- [```account```](./account.md) + +- [```account new```](./account_new.md) + +- [```account list```](./account_list.md) + +- [```account import```](./account_import.md) + +- [```version```](./version.md) diff --git a/docs/cli/account.md b/docs/cli/account.md new file mode 100644 index 0000000000000000000000000000000000000000..00fd6cbe6508b6f02e9c4479f8cd6ba8f481bf94 --- /dev/null +++ b/docs/cli/account.md @@ -0,0 +1,10 @@ + +# Account + +The ```account``` command groups actions to interact with accounts: + +- [```account new```](./account_new.md): Create a new account in the Bor client. + +- [```account list```](./account_list.md): List the wallets in the Bor client. + +- [```account import```](./account_import.md): Import an account to the Bor client. diff --git a/docs/cli/account_import.md b/docs/cli/account_import.md new file mode 100644 index 0000000000000000000000000000000000000000..2a515866cf94ed691097db82f2ba0dd92da4cef6 --- /dev/null +++ b/docs/cli/account_import.md @@ -0,0 +1,4 @@ + +# Account import + +The ```account import``` command imports an account in Json format to the Bor data directory. diff --git a/docs/cli/account_list.md b/docs/cli/account_list.md new file mode 100644 index 0000000000000000000000000000000000000000..4a2d28de92a1d9bb3091b5b982e272e94b9d3f09 --- /dev/null +++ b/docs/cli/account_list.md @@ -0,0 +1,4 @@ + +# Account list + +The ```account list``` command lists all the accounts in the Bor data directory. diff --git a/docs/cli/account_new.md b/docs/cli/account_new.md new file mode 100644 index 0000000000000000000000000000000000000000..41e53767a1b16e839a5be13347e84b0e7473d7ca --- /dev/null +++ b/docs/cli/account_new.md @@ -0,0 +1,4 @@ + +# Account new + +The ```account new``` command creates a new local account file on the Bor data directory. Bor should not be running to execute this command. diff --git a/docs/cli/debug.md b/docs/cli/debug.md new file mode 100644 index 0000000000000000000000000000000000000000..c75ae79e4976d6b980bffd0a9085eb2d4897c529 --- /dev/null +++ b/docs/cli/debug.md @@ -0,0 +1,30 @@ + +# Debug + +The ```bor debug``` command takes a debug dump of the running client. + +## Options + +- ```seconds```: Number of seconds to trace cpu and traces. + +- ```output```: Output directory for the data dump. + +## Examples + +By default it creates a tar.gz file with the output: + +``` +$ bor debug +Starting debugger... + +Created debug archive: bor-debug-2021-10-26-073819Z.tar.gz +``` + +Send the output to a specific directory: + +``` +$ bor debug --output data +Starting debugger... + +Created debug directory: data/bor-debug-2021-10-26-075437Z +``` diff --git a/docs/cli/server.md b/docs/cli/server.md new file mode 100644 index 0000000000000000000000000000000000000000..e2d961579a0299f0265dff8e26f6714c52605fd1 --- /dev/null +++ b/docs/cli/server.md @@ -0,0 +1,192 @@ + +# Server + +The ```bor server``` command runs the Bor client. + +## General Options + +- ```chain```: Name of the chain to sync (mainnet or mumbai). + +- ```log-level```: Set log level for the server (info, warn, debug, trace). + +- ```datadir```: Path of the data directory to store information (defaults to $HOME). + +- ```config```: List of files that contain the configuration. + +- ```syncmode```: Blockchain sync mode ("fast", "full", "snap" or "light"). + +- ```gcmode```: Blockchain garbage collection mode ("full", "archive"). + +- ```whitelist```: Comma separated block number-to-hash mappings to enforce (<number>=<hash>). + +- ```snapshot```: Enables snapshot-database mode (default = enable). + +- ```bor.heimdall```: URL of Heimdall service. + +- ```bor.withoutheimdall```: Run without Heimdall service (for testing purpose). + +- ```ethstats```: Reporting URL of a ethstats service (nodename:secret@host:port). + +- ```gpo.blocks```: Number of recent blocks to check for gas prices. + +- ```gpo.percentile```: Suggested gas price is the given percentile of a set of recent transaction gas prices. + +- ```gpo.maxprice```: Maximum gas price will be recommended by gpo. + +- ```gpo.ignoreprice```: Gas price below which gpo will ignore transactions. + +- ```grpc.addr```: Address and port to bind the GRPC server. + +### Transaction Pool Options + +- ```txpool.locals```: Comma separated accounts to treat as locals (no flush, priority inclusion). + +- ```txpool.nolocals```: Disables price exemptions for locally submitted transactions + +- ```txpool.journal```: Disk journal for local transaction to survive node restarts + +- ```txpool.rejournal```: Time interval to regenerate the local transaction journal + +- ```txpool.pricelimit```: Minimum gas price limit to enforce for acceptance into the pool + +- ```txpool.pricebump```: Price bump percentage to replace an already existing transaction + +- ```txpool.accountslots```: Minimum number of executable transaction slots guaranteed per account + +- ```txpool.globalslots```: Maximum number of executable transaction slots for all accounts + +- ```txpool.accountqueue```: Maximum number of non-executable transaction slots permitted per account + +- ```txpool.globalqueue```: Maximum number of non-executable transaction slots for all accounts + +- ```txpool.lifetime```: Maximum amount of time non-executable transaction are queued + +### Sealer Options + +- ```mine```: Enable sealing. + +- ```miner.etherbase```: Public address for block mining rewards (default = first account) + +- ```miner.extradata```: Block extra data set by the miner (default = client version). + +- ```miner.gaslimit```: Target gas ceiling for mined blocks. + +- ```miner.gasprice```: Minimum gas price for mining a transaction. + +### Cache Options + +- ```cache```: Megabytes of memory allocated to internal caching (default = 4096 mainnet full node). + +- ```cache.database```: Percentage of cache memory allowance to use for database io. + +- ```cache.trie```: Percentage of cache memory allowance to use for trie caching (default = 15% full mode, 30% archive mode). + +- ```cache.trie.journal```: Disk journal directory for trie cache to survive node restarts. + +- ```cache.trie.rejournal```: Time interval to regenerate the trie cache journal. + +- ```cache.gc```: Percentage of cache memory allowance to use for trie pruning (default = 25% full mode, 0% archive mode). + +- ```cache.snapshot```: Percentage of cache memory allowance to use for snapshot caching (default = 10% full mode, 20% archive mode). + +- ```cache.noprefetch```: Disable heuristic state prefetch during block import (less CPU and disk IO, more time waiting for data). + +- ```cache.preimages```: Enable recording the SHA3/keccak preimages of trie keys. + +- ```txlookuplimit```: Number of recent blocks to maintain transactions index for (default = about one year, 0 = entire chain). + +### JsonRPC Options + +- ```rpc.gascap```: Sets a cap on gas that can be used in eth_call/estimateGas (0=infinite). + +- ```rpc.txfeecap```: Sets a cap on transaction fee (in ether) that can be sent via the RPC APIs (0 = no cap). + +- ```ipcdisable```: Disable the IPC-RPC server. + +- ```ipcpath```: Filename for IPC socket/pipe within the datadir (explicit paths escape it). + +- ```jsonrpc.corsdomain```: Comma separated list of domains from which to accept cross. + +- ```jsonrpc.vhosts```: Comma separated list of virtual hostnames from which to accept requests (server enforced). Accepts '*' wildcard. + +- ```jsonrpc.modules```: API's offered over the HTTP-RPC interface. + +- ```http```: Enable the HTTP-RPC server. + +- ```http.addr```: HTTP-RPC server listening interface. + +- ```http.port```: HTTP-RPC server listening port. + +- ```http.rpcprefix```: HTTP path path prefix on which JSON-RPC is served. Use '/' to serve on all paths. + +- ```ws```: Enable the WS-RPC server. + +- ```ws.addr```: WS-RPC server listening interface. + +- ```ws.port```: WS-RPC server listening port. + +- ```ws.rpcprefix```: HTTP path prefix on which JSON-RPC is served. Use '/' to serve on all paths. + +- ```graphql```: Enable GraphQL on the HTTP-RPC server. Note that GraphQL can only be started if an HTTP server is started as well. + +### P2P Options + +- ```bind```: Network binding address + +- ```port```: Network listening port + +- ```bootnodes```: Comma separated enode URLs for P2P discovery bootstrap + +- ```maxpeers```: "Maximum number of network peers (network disabled if set to 0) + +- ```maxpendpeers```: Maximum number of pending connection attempts (defaults used if set to 0) + +- ```nat```: "NAT port mapping mechanism (any|none|upnp|pmp|extip:<IP>) + +- ```nodiscover```: "Disables the peer discovery mechanism (manual peer addition) + +- ```v5disc```: "Enables the experimental RLPx V5 (Topic Discovery) mechanism + +### Telemetry Options + +- ```metrics```: Enable metrics collection and reporting. + +- ```metrics.expensive```: Enable expensive metrics collection and reporting. + +- ```metrics.influxdb```: Enable metrics export/push to an external InfluxDB database (v1). + +- ```metrics.influxdb.endpoint```: InfluxDB API endpoint to report metrics to. + +- ```metrics.influxdb.database```: InfluxDB database name to push reported metrics to. + +- ```metrics.influxdb.username```: Username to authorize access to the database. + +- ```metrics.influxdb.password```: Password to authorize access to the database. + +- ```metrics.influxdb.tags```: Comma-separated InfluxDB tags (key/values) attached to all measurements. + +- ```metrics.influxdbv2```: Enable metrics export/push to an external InfluxDB v2 database. + +- ```metrics.influxdb.token```: Token to authorize access to the database (v2 only). + +- ```metrics.influxdb.bucket```: InfluxDB bucket name to push reported metrics to (v2 only). + +- ```metrics.influxdb.organization```: InfluxDB organization name (v2 only). + +### Account Management Options + +- ```unlock```: "Comma separated list of accounts to unlock. + +- ```password```: Password file to use for non-interactive password input. + +- ```allow-insecure-unlock```: Allow insecure account unlocking when account-related RPCs are exposed by http. + +- ```lightkdf```: Reduce key-derivation RAM & CPU usage at some expense of KDF strength. + +## Usage + +Use multiple files to configure the client: + +``` +$ bor server --config ./legacy-config.toml --config ./config2.hcl +``` diff --git a/docs/cli/version.md b/docs/cli/version.md new file mode 100644 index 0000000000000000000000000000000000000000..156bdf607c0c22aa9586739410b8fac87ff1a5d9 --- /dev/null +++ b/docs/cli/version.md @@ -0,0 +1,11 @@ + +# Version + +The ```bor version``` command outputs the version of the binary. + +## Usage + +``` +$ bor version +0.2.9-stable +``` diff --git a/docs/config.md b/docs/config.md new file mode 100644 index 0000000000000000000000000000000000000000..4f4dec157ba47354729e7d3440ab5a784025ea54 --- /dev/null +++ b/docs/config.md @@ -0,0 +1,133 @@ + +# Config + +Toml files format used in geth are being deprecated. + +Bor uses uses JSON and [HCL](https://github.com/hashicorp/hcl) formats to create configuration files. This is the format in HCL alongside the default values: + +``` +chain = "mainnet" +log-level = "info" +data-dir = "" +sync-mode = "fast" +gc-mode = "full" +snapshot = true +ethstats = "" +whitelist = {} + +p2p { + max-peers = 30 + max-pend-peers = 50 + bind = "0.0.0.0" + port = 30303 + no-discover = false + nat = "any" + discovery { + v5-enabled = false + bootnodes = [] + bootnodesv4 = [] + bootnodesv5 = [] + staticNodes = [] + trustedNodes = [] + dns = [] + } +} + +heimdall { + url = "http://localhost:1317" + without = false +} + +txpool { + locals = [] + no-locals = false + journal = "" + rejournal = "1h" + price-limit = 1 + price-bump = 10 + account-slots = 16 + global-slots = 4096 + account-queue = 64 + global-queue = 1024 + lifetime = "3h" +} + +sealer { + enabled = false + etherbase = "" + gas-ceil = 8000000 + extra-data = "" +} + +gpo { + blocks = 20 + percentile = 60 +} + +jsonrpc { + ipc-disable = false + ipc-path = "" + modules = ["web3", "net"] + cors = ["*"] + vhost = ["*"] + + http { + enabled = false + port = 8545 + prefix = "" + host = "localhost" + } + + ws { + enabled = false + port = 8546 + prefix = "" + host = "localhost" + } + + graphqh { + enabled = false + } +} + +telemetry { + enabled = false + expensive = false + + influxdb { + v1-enabled = false + endpoint = "" + database = "" + username = "" + password = "" + v2-enabled = false + token = "" + bucket = "" + organization = "" + } +} + +cache { + cache = 1024 + perc-database = 50 + perc-trie = 15 + perc-gc = 25 + perc-snapshot = 10 + journal = "triecache" + rejournal = "60m" + no-prefetch = false + preimages = false + tx-lookup-limit = 2350000 +} + +accounts { + unlock = [] + password-file = "" + allow-insecure-unlock = false + use-lightweight-kdf = false +} + +grpc { + addr = ":3131" +} +``` diff --git a/go.mod b/go.mod index 37f278738cb5b78c57b86b714fe5b7c0a8ae7694..c7718bbbbd81eef006840236c105b02feae452be 100644 --- a/go.mod +++ b/go.mod @@ -25,9 +25,11 @@ require ( github.com/fatih/color v1.7.0 github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff + github.com/go-kit/kit v0.9.0 // indirect + github.com/go-logfmt/logfmt v0.5.0 // indirect github.com/go-ole/go-ole v1.2.1 // indirect github.com/go-stack/stack v1.8.0 - github.com/golang/protobuf v1.4.3 + github.com/golang/protobuf v1.5.2 github.com/golang/snappy v0.0.4 github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa github.com/google/uuid v1.1.5 @@ -35,19 +37,23 @@ require ( github.com/graph-gophers/graphql-go v0.0.0-20201113091052-beb923fada29 github.com/hashicorp/go-bexpr v0.1.10 github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d + github.com/hashicorp/hcl/v2 v2.10.1 github.com/holiman/bloomfilter/v2 v2.0.3 github.com/holiman/uint256 v1.2.0 github.com/huin/goupnp v1.0.2 + github.com/imdario/mergo v0.3.11 github.com/influxdata/influxdb v1.8.3 github.com/influxdata/influxdb-client-go/v2 v2.4.0 github.com/influxdata/line-protocol v0.0.0-20210311194329-9aa0e372d097 // indirect github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458 github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e - github.com/julienschmidt/httprouter v1.2.0 + github.com/julienschmidt/httprouter v1.3.0 github.com/karalabe/usb v0.0.0-20211005121534-4c5740d64559 github.com/kylelemons/godebug v1.1.0 // indirect github.com/mattn/go-colorable v0.1.8 github.com/mattn/go-isatty v0.0.12 + github.com/mitchellh/cli v1.1.2 + github.com/mitchellh/go-homedir v1.1.0 github.com/naoina/go-stringutil v0.1.0 // indirect github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416 github.com/olekukonko/tablewriter v0.0.5 @@ -55,6 +61,7 @@ require ( github.com/prometheus/tsdb v0.7.1 github.com/rjeczalik/notify v0.9.1 github.com/rs/cors v1.7.0 + github.com/ryanuber/columnize v2.1.2+incompatible github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4 github.com/stretchr/testify v1.7.0 @@ -62,12 +69,17 @@ require ( github.com/tklauser/go-sysconf v0.3.5 // indirect github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef github.com/xsleonard/go-merkle v1.1.0 + go.opentelemetry.io/otel v1.2.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.2.0 + go.opentelemetry.io/otel/sdk v1.2.0 golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d // indirect golang.org/x/sync v0.0.0-20210220032951-036812b2e83c golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912 golang.org/x/text v0.3.6 golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba + google.golang.org/grpc v1.42.0 + google.golang.org/protobuf v1.27.1 gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6 gopkg.in/urfave/cli.v1 v1.20.0 diff --git a/go.sum b/go.sum index a259f6e030cdf975fe898cf728d6c6c722e77777..96d83f3fcc925fd8f3034f8c4a49a7cbe5dcaca2 100644 --- a/go.sum +++ b/go.sum @@ -33,6 +33,7 @@ github.com/Azure/go-autorest/autorest/date v0.2.0 h1:yW+Zlqf26583pE43KhfnhFcdmSW github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g= github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= +github.com/Azure/go-autorest/autorest/mocks v0.3.0 h1:qJumjCaCudz+OcqE9/XtEPfvtOjOmKaui4EOpFI6zZc= github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM= github.com/Azure/go-autorest/logger v0.1.0 h1:ruG4BSDXONFRrZZJ2GUXDiUyVpayPmb1GnWeHDdaNKY= github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= @@ -41,19 +42,35 @@ github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbt github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= +github.com/Masterminds/goutils v1.1.0 h1:zukEsf/1JZwCMgHiK3GZftabmxiCw4apj3a28RPBiVg= +github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= +github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= +github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= +github.com/Masterminds/sprig v2.22.0+incompatible h1:z4yfnGrZ7netVz+0EDJ0Wi+5VZCSYp4Z0m2dk6cEM60= +github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 h1:fLjPD/aNc3UIOA6tDi6QXUemppXK3P9BI7mr2hd6gx8= github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= github.com/VictoriaMetrics/fastcache v1.6.0 h1:C/3Oi3EiBCqufydp1neRZkqcwmEiuRT9c3fqvvgKm5o= github.com/VictoriaMetrics/fastcache v1.6.0/go.mod h1:0qHz5QP0GMX4pfmMA/zt5RgfNuXJrTP0zS7DqpHGGTw= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/agext/levenshtein v1.2.1 h1:QmvMAjj2aEICytGiWzmxoE0x2KZvE0fvmqMOfy2tjT8= +github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8= github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/apache/arrow/go/arrow v0.0.0-20191024131854-af6fa24be0db/go.mod h1:VTxUBvSJ3s3eHAg65PNgrsn5BtqCRPdmyXh6rAfdxN0= +github.com/apparentlymart/go-dump v0.0.0-20180507223929-23540a00eaa3/go.mod h1:oL81AME2rN47vu18xqj1S1jPIPuN7afo62yKTNn3XMM= +github.com/apparentlymart/go-textseg v1.0.0 h1:rRmlIsPEEhUTIKQb7T++Nz/A5Q6C9IuX2wFoYVvnCs0= +github.com/apparentlymart/go-textseg v1.0.0/go.mod h1:z96Txxhf3xSFMPmb5X/1W05FF/Nj9VFpLOpjS5yuumk= +github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6iT90AvPUL1NNfNw= +github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310 h1:BUAU3CGlLvorLI26FmByPp2eC2qla6E1Tw+scpcg/to= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/aws/aws-sdk-go-v2 v1.2.0 h1:BS+UYpbsElC82gB+2E2jiCBg36i8HlubTB/dO/moQ9c= github.com/aws/aws-sdk-go-v2 v1.2.0/go.mod h1:zEQs02YRBw1DjK0PoJv3ygDYOFTre1ejlJWl8FwAuQo= github.com/aws/aws-sdk-go-v2/config v1.1.1 h1:ZAoq32boMzcaTW9bcUacBswAmHTbvlvDJICgHFZuECo= @@ -74,6 +91,8 @@ github.com/aws/smithy-go v1.1.0 h1:D6CSsM3gdxaGaqXnPgOBCeL6Mophqzu7KJOu7zW78sU= github.com/aws/smithy-go v1.1.0/go.mod h1:EzMw8dbp/YJL4A5/sbhGddag+NPT7q084agLbB9LgIw= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bmizerany/pat v0.0.0-20170815010413-6226ea591a40/go.mod h1:8rLXio+WjiTceGBHIoTvn60HIbs7Hm7bcHjyrSqYB9c= github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= github.com/btcsuite/btcd v0.20.1-beta h1:Ik4hyJqN8Jfyv3S4AGBOmyouMsYE3EdYODkMbQjwPGw= @@ -86,6 +105,8 @@ github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= github.com/c-bata/go-prompt v0.2.2/go.mod h1:VzqtzE2ksDBcdln8G7mk2RX9QyGjH+OVqOCSiVIqS34= +github.com/cenkalti/backoff/v4 v4.1.1 h1:G2HAfAmvm/GcKan2oOQpBXOd2tT2G57ZnZGWa1PxPBQ= +github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk= github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= @@ -99,6 +120,12 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMn github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cloudflare/cloudflare-go v0.14.0 h1:gFqGlGl/5f9UGXAaKapCGUfaTCgRKKnzu2VvzMZlOFA= github.com/cloudflare/cloudflare-go v0.14.0/go.mod h1:EnwdgGMaFOruiPZRFSgn+TsQ3hQ7C/YWzIGLeu5c304= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= +github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/consensys/bavard v0.1.8-0.20210406032232-f3452dc9b572/go.mod h1:Bpd0/3mZuaj6Sj+PqrmIquiOKy397AKGThQPaGzNXAQ= github.com/consensys/gnark-crypto v0.4.1-0.20210426202927-39ac3d4b3f1f h1:C43yEtQ6NIf4ftFXD/V55gnGFgPbMQobd//YlnLjUJ8= github.com/consensys/gnark-crypto v0.4.1-0.20210426202927-39ac3d4b3f1f/go.mod h1:815PAHg3wvysy0SyIqanF8gZ0Y1wjk/hrDHD/iT88+Q= @@ -129,7 +156,11 @@ github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA github.com/eclipse/paho.mqtt.golang v1.2.0/go.mod h1:H9keYFcgq3Qr5OUJm/JZI/i6U7joQ8SYLhZwfeOo6Ts= github.com/edsrzf/mmap-go v1.0.0 h1:CEBF7HpRnUCSJgGUb5h1Gm7e3VkmVDrR8lvWVLtrOFw= github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= @@ -149,11 +180,13 @@ github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1T github.com/go-chi/chi/v5 v5.0.0/go.mod h1:BBug9lr0cqtdAhsu6R4AAdvufI0/XBzAQSsUqJpoZOs= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-kit/kit v0.8.0 h1:Wz+5lgoB0kkuqLEc6NVmwRknTKP6dTGbSqvhZtBI/j0= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.9.0 h1:wDJmvq38kDhkVxi50ni9ykkdUr1PKgqKOoi01fa0Mdk= +github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0 h1:MP4Eh7ZCb31lleYCFuwm0oe4/YGak+5l1vA2NOE80nA= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-logfmt/logfmt v0.5.0 h1:TrB8swr/68K7m9CcGut2g3UOihhbcbiMAYiuTXdEih4= +github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-ole/go-ole v1.2.1 h1:2lOsA72HgjxAuMlKpFiCbHTvu44PIVkZ5hqm3RSdI/E= github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= @@ -163,6 +196,8 @@ github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5Nq github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68= +github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/gofrs/uuid v3.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= @@ -174,17 +209,23 @@ github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4er github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= @@ -198,8 +239,11 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa h1:Q75Upo5UN4JbPFURXZ8nLKYUvF85dyFRop/vQ0Rv+64= github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= @@ -207,6 +251,7 @@ github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OI github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.5 h1:kxhtnfFVi+rYdOALN0B3k9UT86zVJKfBimRaciULW4I= github.com/google/uuid v1.1.5/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= @@ -217,21 +262,33 @@ github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0U github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/graph-gophers/graphql-go v0.0.0-20201113091052-beb923fada29 h1:sezaKhEfPFg8W0Enm61B9Gs911H8iesGY5R8NDPtd1M= github.com/graph-gophers/graphql-go v0.0.0-20201113091052-beb923fada29/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= +github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpxn4uE= github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= +github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d h1:dg1dEPuWpEqDnvIw251EVy4zlP8gWbsGj4BsUKCRpYs= github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/hcl/v2 v2.10.1 h1:h4Xx4fsrRE26ohAk/1iGF/JBqRQbyUqu5Lvj60U54ys= +github.com/hashicorp/hcl/v2 v2.10.1/go.mod h1:FwWsfWEjyV/CMj8s/gqAuiviY72rJ1/oayI9WftqcKg= github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= github.com/holiman/uint256 v1.2.0 h1:gpSYcPLWGv4sG43I2mVLiDZCNDh/EpGjSk8tmtxitHM= github.com/holiman/uint256 v1.2.0/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/huandu/xstrings v1.3.2 h1:L18LIDzqlW6xN2rEkpdV8+oL/IXWJ1APd+vsdYy4Wdw= +github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/huin/goupnp v1.0.2 h1:RfGLP+h3mvisuWEyybxNq5Eft3NWhHLPeUN72kpKZoI= github.com/huin/goupnp v1.0.2/go.mod h1:0dxJBVBHqTMjIUMkESDTNgOOx/Mw5wYIfyFmdzSamkM= github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/imdario/mergo v0.3.11 h1:3tnifQM4i+fbajXKBHXWEH+KvNHqojZ778UH75j3bGA= +github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/influxdata/flux v0.65.1/go.mod h1:J754/zds0vvpfwuq7Gc2wRdVwEodfpCFM7mYlOw2LqY= github.com/influxdata/influxdb v1.8.3 h1:WEypI1BQFTT4teLM+1qkEcvUi0dAvopAI/ir0vAiBg8= @@ -260,8 +317,9 @@ github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1 github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jsternberg/zap-logfmt v1.0.0/go.mod h1:uvPs/4X51zdkcm5jXl5SYoN+4RK21K8mysFmDaM/h+o= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/julienschmidt/httprouter v1.2.0 h1:TDTW5Yz1mjftljbcKqRcrYhd4XeOoI98t+9HbQbYf7g= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U= +github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= github.com/jwilder/encoding v0.0.0-20170811194829-b4e1701a28ef/go.mod h1:Ct9fl0F6iIOGgxJ5npU/IUOhOhqlVrGjyIZc8/MagT0= github.com/karalabe/usb v0.0.0-20211005121534-4c5740d64559 h1:0VWDXPNE0brOek1Q8bLfzKkvOzwbQE/snjGojlCr8CY= @@ -274,7 +332,6 @@ github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5/go.mod h1:Pj4uuM52 github.com/klauspost/crc32 v0.0.0-20161016154125-cb6bfca970f6/go.mod h1:+ZoRqAPRLkC4NPOvfYeR5KNOrY6TD+/sAC3HXPZgDYg= github.com/klauspost/pgzip v1.0.2-0.20170402124221-0bf5dcad4ada/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= @@ -283,6 +340,7 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/labstack/echo/v4 v4.2.1/go.mod h1:AA49e0DZ8kk5jTOOCKNuPR6oTnBS0dYiM4FW1e6jwpg= @@ -301,6 +359,7 @@ github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d h1:oNAwILwmgWKFpuU+dXvI6dl9jG2mAWAZLX3r9s0PPiw= github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= +github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= @@ -312,10 +371,20 @@ github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-tty v0.0.0-20180907095812-13ff1204f104/go.mod h1:XPvLUNfbS4fJH25nqRHfWLMa1ONC8Amw+mIA639KxkE= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/mitchellh/cli v1.1.2 h1:PvH+lL2B7IQ101xQL63Of8yFS2y+aDlsFcsqNc+u/Kw= +github.com/mitchellh/cli v1.1.2/go.mod h1:6iaV0fGdElS6dPBx0EApTxHrcWvmJphyh2n8YBLPPZ4= +github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ= +github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= +github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 h1:DpOJ2HYzCv8LZP15IdmG+YdwD2luVPHITV96TkirNBM= +github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag= github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/pointerstructure v1.2.0 h1:O+i9nHnXS3l/9Wu7r4NrEdwA2VFTicjUEN1uBnDo34A= github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= +github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY= +github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae/go.mod h1:qAyveg+e4CE+eKJXWVjKXM4ck2QobLqTDytGJbLLhJg= @@ -355,6 +424,8 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/term v0.0.0-20180730021639-bffc007b7fd5/go.mod h1:eCbImbZ95eXtAUIbLAuAVnBnwf83mjf6QIVH8SHYwqQ= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/posener/complete v1.1.1 h1:ccV59UEOTzVDnDUEFdT95ZzHVZ+5+158q8+SJb2QV5w= +github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= @@ -370,12 +441,16 @@ github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40T github.com/retailnext/hllpp v1.0.1-0.20180308014038-101a6d2f8b52/go.mod h1:RDpi1RftBQPUCDRw6SmxeaREsAaRKnOclghuzp/WRzc= github.com/rjeczalik/notify v0.9.1 h1:CLCKso/QK1snAlnhNR/CNvNiFU2saUtjV0bx3EwNeCE= github.com/rjeczalik/notify v0.9.1/go.mod h1:rKwnCoCGeuQnwBtTSPL9Dad03Vh2n40ePRrjvIXnJho= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ryanuber/columnize v2.1.2+incompatible h1:C89EOx/XBWwIXl8wm8OPJBd7kPF25UfsK2X7Ph/zCAk= +github.com/ryanuber/columnize v2.1.2+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/segmentio/kafka-go v0.1.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo= github.com/segmentio/kafka-go v0.2.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo= +github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible h1:Bn1aCHHRnjv4Bl16T8rcaFjYSrGrIZvpiGO6P3Q4GpU= github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= @@ -386,6 +461,7 @@ github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9 github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4 h1:Gb2Tyox57NRNuZ2d3rmvB3pcmbu7O1RS3m8WRx7ilrg= github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4/go.mod h1:RZLeN1LMWmRsyYjvAu+I6Dm9QmlDaIIt+Y+4Kd7Tp+Q= @@ -397,6 +473,7 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= @@ -412,20 +489,41 @@ github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/X github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= +github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= +github.com/vmihailenco/msgpack/v4 v4.3.12/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4= +github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= github.com/willf/bitset v1.1.3/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= github.com/xlab/treeprint v0.0.0-20180616005107-d6fb6747feb6/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg= github.com/xsleonard/go-merkle v1.1.0 h1:fHe1fuhJjGH22ZzVTAH0jqHLhTGhOq3wQjJN+8P0jQg= github.com/xsleonard/go-merkle v1.1.0/go.mod h1:cW4z+UZ/4f2n9IJgIiyDCdYguchoDyDAPmpuOWGxdGg= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/zclconf/go-cty v1.2.0/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8= +github.com/zclconf/go-cty v1.8.0 h1:s4AvqaeQzJIu3ndv4gVIhplVD0krU+bgrcLSVUnaWuA= +github.com/zclconf/go-cty v1.8.0/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUAzyuvAk= +github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b/go.mod h1:ZRKQfBXbGkpdV6QMzT3rU1kSTAnfu1dO8dPKjYprgj8= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opentelemetry.io/otel v1.2.0 h1:YOQDvxO1FayUcT9MIhJhgMyNO1WqoduiyvQHzGN0kUQ= +go.opentelemetry.io/otel v1.2.0/go.mod h1:aT17Fk0Z1Nor9e0uisf98LrntPGMnk4frBO9+dkf69I= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.2.0 h1:xzbcGykysUh776gzD1LUPsNNHKWN0kQWDnJhn1ddUuk= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.2.0/go.mod h1:14T5gr+Y6s2AgHPqBMgnGwp04csUjQmYXFWPeiBoq5s= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.2.0 h1:VsgsSCDwOSuO8eMVh63Cd4nACMqgjpmAeJSIvVNneD0= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.2.0/go.mod h1:9mLBBnPRf3sf+ASVH2p9xREXVBvwib02FxcKnavtExg= +go.opentelemetry.io/otel/sdk v1.2.0 h1:wKN260u4DesJYhyjxDa7LRFkuhH7ncEVKU37LWcyNIo= +go.opentelemetry.io/otel/sdk v1.2.0/go.mod h1:jNN8QtpvbsKhgaC6V5lHiejMoKD+V8uadoSafgHPx1U= +go.opentelemetry.io/otel/trace v1.2.0 h1:Ys3iqbqZhcf28hHzrm5WAquMkDHNZTUkw7KHbuNjej0= +go.opentelemetry.io/otel/trace v1.2.0/go.mod h1:N5FLswTubnxKxOJHM7XZC074qpeEdLy3CgAVsdMucK0= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +go.opentelemetry.io/proto/otlp v0.10.0 h1:n7brgtEbDvXEgGyKKo8SobKT1e9FewlDtXzkVP5djoE= +go.opentelemetry.io/proto/otlp v0.10.0/go.mod h1:zG20xCK0szZ1xdokeSOwEcmlXu+x9kkdRe6N1DhKcfU= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190909091759-094676da4a83/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -464,6 +562,7 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -478,6 +577,7 @@ golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= @@ -512,6 +612,7 @@ golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -538,6 +639,7 @@ golang.org/x/sys v0.0.0-20210316164454-77fc1eacc6aa/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210420205809-ac73e9fd8988/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912 h1:uCLL3g5wH2xjxVREVuAbP9JM5PPKjRbXKRa6IBjkzmU= golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= @@ -620,18 +722,34 @@ google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvx google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200108215221-bd8f9a0ef82f/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k= +google.golang.org/grpc v1.42.0 h1:XT2/MFpuPFsEX2fWh3YQtHkZ+WYZFQRfaUgLZYj/p6A= +google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/miner/worker.go b/miner/worker.go index 5399adf1def6afcd9d2569a8bb263e23f96b69e4..8654e439c45438d48f282ee0ff4270afe3749ba9 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -616,6 +616,15 @@ func (w *worker) resultLoop() { if w.chain.HasBlock(block.Hash(), block.NumberU64()) { continue } + oldBlock := w.chain.GetBlockByNumber(block.NumberU64()) + if oldBlock != nil { + oldBlockAuthor, _ := w.chain.Engine().Author(oldBlock.Header()) + newBlockAuthor, _ := w.chain.Engine().Author(block.Header()) + if oldBlockAuthor == newBlockAuthor { + log.Info("same block ", "height", block.NumberU64()) + continue + } + } var ( sealhash = w.engine.SealHash(block.Header()) hash = block.Hash() diff --git a/scripts/tools-protobuf.sh b/scripts/tools-protobuf.sh new file mode 100644 index 0000000000000000000000000000000000000000..020639f9d9406760d14376afa7023bfdc7c1093a --- /dev/null +++ b/scripts/tools-protobuf.sh @@ -0,0 +1,5 @@ +curl -LO https://github.com/protocolbuffers/protobuf/releases/download/v3.12.0/protoc-3.12.0-linux-x86_64.zip +sudo unzip protoc-3.12.0-linux-x86_64.zip -d /usr/local/bin + +go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.25.0 +go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.1