From 953f348d1ec3b99afd2cf6d65b93db91e9fef1ab Mon Sep 17 00:00:00 2001
From: Alex Sharov <AskAlexSharov@gmail.com>
Date: Thu, 2 Sep 2021 12:55:04 +0700
Subject: [PATCH] Pool: add grpc server (#2615)

---
 README.md               | 27 ++++++++++++++++++---------
 cmd/txpool/main.go      | 15 ++++++++++++---
 ethdb/privateapi/all.go | 12 ++++++++----
 go.mod                  |  2 +-
 go.sum                  |  4 ++--
 5 files changed, 41 insertions(+), 19 deletions(-)

diff --git a/README.md b/README.md
index e840dc5eaa..5a091eb7d2 100644
--- a/README.md
+++ b/README.md
@@ -133,15 +133,17 @@ Windows users may run erigon in 3 possible ways:
 
 ### Beacon Chain
 
-Erigon can be used as an execution-layer for beacon chain consensus clients (Eth2). Default configuration is ok. Eth2 
-rely on availability of receipts - don't prune them: don't add 
-character `r` to `--prune` flag or set large `--prune.r.older=2_000_000`.
+Erigon can be used as an execution-layer for beacon chain consensus clients (Eth2). Default configuration is ok. Eth2
+rely on availability of receipts - don't prune them: don't add character `r` to `--prune` flag or set
+large `--prune.r.older=2_000_000`.
 
 You must run the [JSON-RPC daemon](#json-rpc-daemon) in addition to the Erigon.
 
-If beacon chain client on a different device: add `--http.addr 0.0.0.0` (JSON-RPC daemon listen on localhost by default).
+If beacon chain client on a different device: add `--http.addr 0.0.0.0` (JSON-RPC daemon listen on localhost by default)
+.
 
-Once the JSON-RPC daemon is running, all you need to do is point your beacon chain client to `<ip address>:8545`, where <ip address> is either localhost or the IP address of the device running the JSON-RPC daemon.
+Once the JSON-RPC daemon is running, all you need to do is point your beacon chain client to `<ip address>:8545`,
+where <ip address> is either localhost or the IP address of the device running the JSON-RPC daemon.
 
 Erigon has been tested with Lighthouse however all other clients that support JSON-RPC should also work.
 
@@ -274,15 +276,18 @@ Detailed explanation: [./docs/programmers_guide/db_faq.md](./docs/programmers_gu
 ### Default Ports and Protocols / Firewalls?
 
 #### `erigon` ports
+
 |  Port |  Protocol |      Purpose     |  Expose |
 |:-----:|:---------:|:----------------:|:-------:|
 | 30303 | TCP & UDP |  eth/66 peering  |  Public |
 | 30304 | TCP & UDP |  eth/65 peering  |  Public |
 |  9090 |    TCP    | gRPC Connections | Private |
 
-Typically 30303 and 30304 are exposed to the internet to allow incoming peering connections. 9090 is exposed only internally for rpcdaemon or other connections, (e.g. rpcdaemon -> erigon)
+Typically 30303 and 30304 are exposed to the internet to allow incoming peering connections. 9090 is exposed only
+internally for rpcdaemon or other connections, (e.g. rpcdaemon -> erigon)
 
 #### `rpcdaemon` ports
+
 |  Port |  Protocol |      Purpose      |  Expose |
 |:-----:|:---------:|:-----------------:|:-------:|
 |  8545 |    TCP    | HTTP & WebSockets | Private |
@@ -290,22 +295,26 @@ Typically 30303 and 30304 are exposed to the internet to allow incoming peering
 Typically 8545 is exposed only interally for JSON-RPC queries. Both HTTP and WebSocket connections are on the same port.
 
 #### `sentry` ports
+
 |  Port |  Protocol |      Purpose     |  Expose |
 |:-----:|:---------:|:----------------:|:-------:|
 | 30303 | TCP & UDP |      Peering     |  Public |
 |  9091 |    TCP    | gRPC Connections | Private |
 
-Typically a sentry process will run one eth/xx protocl (e.g. eth/66) and will be exposed to the internet on 30303. Port 9091 is for internal gRCP connections (e.g erigon -> sentry)
+Typically a sentry process will run one eth/xx protocl (e.g. eth/66) and will be exposed to the internet on 30303. Port
+9091 is for internal gRCP connections (e.g erigon -> sentry)
 
 #### Other ports
+
 | Port | Protocol | Purpose |  Expose |
 |:----:|:--------:|:-------:|:-------:|
 | 6060 |    TCP   |  pprof  | Private |
 | 6060 |    TCP   | metrics | Private |
 
-Optional flags can be enabled that enable pprof or metrics (or both) - however, they both run on 6060 by default, so you'll have to change one if you want to run both at the same time. use `--help` with the binary for more info.
+Optional flags can be enabled that enable pprof or metrics (or both) - however, they both run on 6060 by default, so
+you'll have to change one if you want to run both at the same time. use `--help` with the binary for more info.
 
-Also, ports 9092 and 9093 are reserved for future use of the consensus engine and shapshot downloader for gRPC (work in progress).
+Reserved for future use: **gRPC ports**: `9092` consensus engine, `9093` snapshot downloader, `9094` TxPool
 
 Getting in touch
 ================
diff --git a/cmd/txpool/main.go b/cmd/txpool/main.go
index 3b4a284b9e..049457383f 100644
--- a/cmd/txpool/main.go
+++ b/cmd/txpool/main.go
@@ -25,6 +25,7 @@ import (
 var (
 	sentryAddr     []string // Address of the sentry <host>:<port>
 	privateApiAddr string
+	txpoolApiAddr  string
 	datadir        string // Path to td working dir
 
 	TLSCertfile string
@@ -35,7 +36,8 @@ var (
 func init() {
 	utils.CobraFlags(rootCmd, append(debug.Flags, utils.MetricFlags...))
 	rootCmd.Flags().StringSliceVar(&sentryAddr, "sentry.api.addr", []string{"localhost:9091"}, "comma separated sentry addresses '<host>:<port>,<host>:<port>'")
-	rootCmd.Flags().StringVar(&privateApiAddr, "private.api.addr", "localhost:9090", "comma separated sentry addresses '<host>:<port>,<host>:<port>'")
+	rootCmd.Flags().StringVar(&privateApiAddr, "private.api.addr", "localhost:9090", "execution service <host>:<port>")
+	rootCmd.Flags().StringVar(&txpoolApiAddr, "txpool.api.addr", "localhost:9094", "txpool service <host>:<port>")
 	rootCmd.Flags().StringVar(&datadir, utils.DataDirFlag.Name, paths.DefaultDataDir(), utils.DataDirFlag.Usage)
 	if err := rootCmd.MarkFlagDirname(utils.DataDirFlag.Name); err != nil {
 		panic(err)
@@ -86,7 +88,7 @@ var rootCmd = &cobra.Command{
 		}
 
 		newTxs := make(chan txpool.Hashes, 1024)
-		txPool, err := txpool.New(newTxs, txPoolDB, txpool.DefaultConfig)
+		txPool, err := txpool.New(newTxs, txPoolDB, coreDB, txpool.DefaultConfig)
 		if err != nil {
 			return err
 		}
@@ -96,8 +98,15 @@ var rootCmd = &cobra.Command{
 		fetcher.ConnectSentries()
 
 		send := txpool.NewSend(cmd.Context(), sentryClients, txPool)
+		txpoolGrpcServer := txpool.NewGrpcServer(cmd.Context(), txPool, txPoolDB)
+		grpcServer, err := txpool.StartGrpc(txpoolGrpcServer, nil, txpoolApiAddr, nil)
+		if err != nil {
+			return err
+		}
+
+		txpool.MainLoop(cmd.Context(), txPoolDB, coreDB, txPool, newTxs, send, txpoolGrpcServer.NewSlotsStreams)
 
-		txpool.BroadcastLoop(cmd.Context(), txPoolDB, coreDB, txPool, newTxs, send)
+		grpcServer.GracefulStop()
 		return nil
 	},
 }
diff --git a/ethdb/privateapi/all.go b/ethdb/privateapi/all.go
index 7a71989da1..17641fbed6 100644
--- a/ethdb/privateapi/all.go
+++ b/ethdb/privateapi/all.go
@@ -9,7 +9,7 @@ import (
 	grpc_recovery "github.com/grpc-ecosystem/go-grpc-middleware/recovery"
 	//grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus"
 	"github.com/ledgerwatch/erigon-lib/gointerfaces/remote"
-	"github.com/ledgerwatch/erigon-lib/gointerfaces/txpool"
+	txpool_proto "github.com/ledgerwatch/erigon-lib/gointerfaces/txpool"
 	"github.com/ledgerwatch/erigon/ethdb/remotedbserver"
 	"github.com/ledgerwatch/log/v3"
 	"google.golang.org/grpc"
@@ -17,7 +17,7 @@ import (
 	"google.golang.org/grpc/keepalive"
 )
 
-func StartGrpc(kv *remotedbserver.KvServer, ethBackendSrv *EthBackendServer, txPoolServer *TxPoolServer, miningServer *MiningServer, addr string, rateLimit uint32, creds *credentials.TransportCredentials) (*grpc.Server, error) {
+func StartGrpc(kv *remotedbserver.KvServer, ethBackendSrv *EthBackendServer, txPoolServer txpool_proto.TxpoolServer, miningServer txpool_proto.MiningServer, addr string, rateLimit uint32, creds *credentials.TransportCredentials) (*grpc.Server, error) {
 	log.Info("Starting private RPC server", "on", addr)
 	lis, err := net.Listen("tcp", addr)
 	if err != nil {
@@ -59,8 +59,12 @@ func StartGrpc(kv *remotedbserver.KvServer, ethBackendSrv *EthBackendServer, txP
 	}
 	grpcServer = grpc.NewServer(opts...)
 	remote.RegisterETHBACKENDServer(grpcServer, ethBackendSrv)
-	txpool.RegisterTxpoolServer(grpcServer, txPoolServer)
-	txpool.RegisterMiningServer(grpcServer, miningServer)
+	if txPoolServer != nil {
+		txpool_proto.RegisterTxpoolServer(grpcServer, txPoolServer)
+	}
+	if miningServer != nil {
+		txpool_proto.RegisterMiningServer(grpcServer, miningServer)
+	}
 	remote.RegisterKVServer(grpcServer, kv)
 
 	//if metrics.Enabled {
diff --git a/go.mod b/go.mod
index 35ce51f3fb..d8a0d4f87f 100644
--- a/go.mod
+++ b/go.mod
@@ -37,7 +37,7 @@ require (
 	github.com/julienschmidt/httprouter v1.3.0
 	github.com/kevinburke/go-bindata v3.21.0+incompatible
 	github.com/kylelemons/godebug v1.1.0 // indirect
-	github.com/ledgerwatch/erigon-lib v0.0.0-20210901082817-3b3384e6675a
+	github.com/ledgerwatch/erigon-lib v0.0.0-20210902033502-9a18ff491cfd
 	github.com/ledgerwatch/log/v3 v3.3.0
 	github.com/ledgerwatch/secp256k1 v0.0.0-20210626115225-cd5cd00ed72d
 	github.com/logrusorgru/aurora/v3 v3.0.0
diff --git a/go.sum b/go.sum
index 47370c88a4..a63753c2be 100644
--- a/go.sum
+++ b/go.sum
@@ -492,8 +492,8 @@ github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0
 github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
 github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c=
 github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8=
-github.com/ledgerwatch/erigon-lib v0.0.0-20210901082817-3b3384e6675a h1:ZHD7Vu9Tw+NOCDXpna/DdXdBer8aAroS+nGZNJttM/U=
-github.com/ledgerwatch/erigon-lib v0.0.0-20210901082817-3b3384e6675a/go.mod h1:q+AQKX1ij+xDBKKPwI3XgV09dwPpukXR1fE22ResK0M=
+github.com/ledgerwatch/erigon-lib v0.0.0-20210902033502-9a18ff491cfd h1:qxT/ADKeSawxwPzA8p3wsm4wmZf+Mgb09p2o8Z+nkXw=
+github.com/ledgerwatch/erigon-lib v0.0.0-20210902033502-9a18ff491cfd/go.mod h1:q846JoG0oCWU9xTunmQAysfywjyoUzxx/5tHPo/F0t0=
 github.com/ledgerwatch/log/v3 v3.3.0 h1:k8N/3NQLILr8CKCMyza261vLFKU7VA+nMNNb0wVyQSc=
 github.com/ledgerwatch/log/v3 v3.3.0/go.mod h1:J58eOHHrIYHxl7LKkRsb/0YibKwtLfauUryl5SLRGm0=
 github.com/ledgerwatch/secp256k1 v0.0.0-20210626115225-cd5cd00ed72d h1:/IKMrJdfRsoYNc36PXqP4xMH3vhW/8IQyBKGQbKZUno=
-- 
GitLab