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: &params.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: &params.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: &params.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: &params.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