From 4d13db38b4a240cc63db6ad6f4f00324f8957c53 Mon Sep 17 00:00:00 2001 From: Bogdan Ovsiannikov Date: Thu, 13 Aug 2020 12:40:43 +0300 Subject: [PATCH] [NOD-1151] Added gRPC server for seeding peers --- .gitignore | 1 + cmd/get_peers_list.go | 35 +++++++++++++++ config.go | 4 ++ dnsseed.go | 40 +++++++++++++++++ go.mod | 3 ++ go.sum | 19 +------- grpc.go | 101 ++++++++++++++++++++++++++++++++++++++++++ grpc_test.go | 99 +++++++++++++++++++++++++++++++++++++++++ test.sh | 45 +++++++++++++++++++ 9 files changed, 329 insertions(+), 18 deletions(-) create mode 100644 cmd/get_peers_list.go create mode 100644 grpc.go create mode 100644 grpc_test.go create mode 100755 test.sh diff --git a/.gitignore b/.gitignore index 7253f83d..d457b6b9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ # Temp files *~ +testdata # Databases kaspad.db diff --git a/cmd/get_peers_list.go b/cmd/get_peers_list.go new file mode 100644 index 00000000..2ad7f744 --- /dev/null +++ b/cmd/get_peers_list.go @@ -0,0 +1,35 @@ +package main + +import ( + "fmt" + "github.com/kaspanet/kaspad/rpc/client" + "strings" +) + +func main() { + connCfg := &client.ConnConfig{ + Host: "localhost:16630", + User: "test", + Pass: "test", + HTTPPostMode: true, + DisableTLS: true, + } + cl, err := client.New(connCfg, nil) + if err != nil { + panic(err) + } + + res, err := cl.GetPeerAddresses() + + if err != nil { + panic(err) + } + + var ips []string + + for _, address := range res.Addresses { + ips = append(ips, address.Addr) + } + + fmt.Printf(strings.Join(ips, ",")) +} diff --git a/config.go b/config.go index e0455fa5..bd005227 100644 --- a/config.go +++ b/config.go @@ -25,6 +25,7 @@ const ( defaultLogFilename = "dnsseeder.log" defaultErrLogFilename = "dnsseeder_err.log" defaultListenPort = "5354" + defaultGrpcListenPort = "3737" ) var ( @@ -44,12 +45,14 @@ func ActiveConfig() *ConfigFlags { // ConfigFlags holds the configurations set by the command line argument type ConfigFlags struct { + KnownPeers string `short:"p" long:"peers" description:"List of already known peer addresses"` ShowVersion bool `short:"V" long:"version" description:"Display version information and exit"` Host string `short:"H" long:"host" description:"Seed DNS address"` Listen string `long:"listen" short:"l" description:"Listen on address:port"` Nameserver string `short:"n" long:"nameserver" description:"hostname of nameserver"` Seeder string `short:"s" long:"default-seeder" description:"IP address of a working node"` Profile string `long:"profile" description:"Enable HTTP profiling on given port -- NOTE port must be between 1024 and 65536"` + GRPCListen string `long:"grpcport" description:"Listen gRPC requests on address:port"` config.NetworkFlags } @@ -76,6 +79,7 @@ func loadConfig() (*ConfigFlags, error) { // Default config. activeConfig = &ConfigFlags{ Listen: normalizeAddress("localhost", defaultListenPort), + GRPCListen: normalizeAddress("localhost", defaultGrpcListenPort), } preCfg := activeConfig diff --git a/dnsseed.go b/dnsseed.go index 80e5cd20..e01f366f 100644 --- a/dnsseed.go +++ b/dnsseed.go @@ -15,6 +15,7 @@ import ( "net" "os" "strconv" + "strings" "sync" "sync/atomic" "time" @@ -62,6 +63,38 @@ func creep() { return } + var knownPeers []*wire.NetAddress + + if len(ActiveConfig().KnownPeers) != 0 { + + for _, p := range strings.Split(ActiveConfig().KnownPeers, ",") { + addressStr := strings.Split(p, ":") + if len(addressStr) != 2 { + log.Errorf("Invalid peer address: %s; addresses should be in format \"IP\":\"port\"", p) + return + } + + ip := net.ParseIP(addressStr[0]) + if ip == nil { + log.Errorf("Invalid peer IP address: %s", addressStr[0]) + return + } + port, err := strconv.Atoi(addressStr[1]) + if err != nil { + log.Errorf("Invalid peer port: %s", addressStr[1]) + return + } + + knownPeers = append(knownPeers, wire.NewNetAddressIPPort(ip, uint16(port), requiredServices)) + } + + amgr.AddAddresses(knownPeers) + for _, peer := range knownPeers { + amgr.Good(peer.IP, peer.Services, nil) + amgr.Attempt(peer.IP) + } + } + var wgCreep sync.WaitGroup for { peers := amgr.Addresses() @@ -196,6 +229,13 @@ func main() { wg.Add(1) spawn("main-DNSServer.Start", dnsServer.Start) + grpcServer := NewGRPCServer(amgr) + err = grpcServer.Start(cfg.GRPCListen) + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to start gRPC server") + return + } + defer func() { log.Infof("Gracefully shutting down the seeder...") atomic.StoreInt32(&systemShutdown, 1) diff --git a/go.mod b/go.mod index c247ffd9..9bdbf51b 100644 --- a/go.mod +++ b/go.mod @@ -3,10 +3,13 @@ module github.com/kaspanet/dnsseeder go 1.14 require ( + github.com/golang/protobuf v1.4.1 github.com/jessevdk/go-flags v1.4.0 github.com/kaspanet/kaspad v0.6.9 github.com/miekg/dns v1.1.25 github.com/pkg/errors v0.9.1 + google.golang.org/grpc v1.30.0 + google.golang.org/protobuf v1.25.0 ) replace github.com/kaspanet/kaspad => ../kaspad diff --git a/go.sum b/go.sum index fbb327b3..6a0b8613 100644 --- a/go.sum +++ b/go.sum @@ -2,6 +2,7 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd h1:R/opQEbFEy9JGkIguV40SvRY1uliPX8ifOvi6ICsFCw= github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= +github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792 h1:R8vQdOQdZ9Y3SkEwmHoWBmX1DNXhXZqlTpq6s4tyJGc= 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/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -13,12 +14,10 @@ github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymF 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/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= 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.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= @@ -39,37 +38,27 @@ 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.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jrick/logrotate v1.0.0 h1:lQ1bL/n9mBNeIXoTUoYRlK4dHuNJVofX9oWqBtPnSzI= github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= -github.com/kaspanet/go-secp256k1 v0.0.2 h1:KZGXddYHxzS02rx6EPPQYYe2tZ/rREj4P6XxgQQwQIw= github.com/kaspanet/go-secp256k1 v0.0.2/go.mod h1:W9OcWBKzH8P/PN2WAUn9k2YmZG/Uc660WAL1NTS3G3M= -github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/miekg/dns v1.1.25 h1:dFwPR6SfLtrSwgDcIq2bcU/gVutB4sNApq2HBdqcakg= github.com/miekg/dns v1.1.25/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= -github.com/onsi/ginkgo v1.6.0 h1:Ix8l273rp3QzYgXSR+c8d1fTG7UPgYkOSELPhiY/YGw= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE= -github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= github.com/syndtr/goleveldb v1.0.1-0.20190923125748-758128399b1d h1:gZZadD8H+fF+n9CmNhYL1Y0dJB+kLOmKd7FbPJLeGHs= github.com/syndtr/goleveldb v1.0.1-0.20190923125748-758128399b1d/go.mod h1:9OrXJhf154huy1nPWmuSrkgjPUtUNhA+Zmy+6AESzuA= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59 h1:3zb4D3T4G8jdExgVU/95+vQXfpEPiMdCaZgmGVxjNHM= golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -90,7 +79,6 @@ golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -133,19 +121,14 @@ google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQ 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.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 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/grpc.go b/grpc.go new file mode 100644 index 00000000..e3ba642c --- /dev/null +++ b/grpc.go @@ -0,0 +1,101 @@ +package main + +import ( + "context" + "fmt" + pb2 "github.com/kaspanet/kaspad/dnsseed/pb" +"github.com/kaspanet/kaspad/util/subnetworkid" + "github.com/kaspanet/kaspad/wire" + "github.com/miekg/dns" + "github.com/pkg/errors" + "google.golang.org/grpc" + "net" +) + +type GRPCServer interface { + Start(listenInterface string) error + Stop() +} + +type grpcServer struct { + pb2.UnimplementedPeerServiceServer + + server *grpc.Server + amgr *Manager +} + +func NewGRPCServer(amgr *Manager) GRPCServer { + return &grpcServer{ amgr: amgr } +} + +func (s *grpcServer) Start(listenInterface string) error { + s.server = grpc.NewServer() + pb2.RegisterPeerServiceServer(s.server, s) + + lis, err := net.Listen("tcp", fmt.Sprintf(listenInterface)) + if err != nil { + return errors.WithStack(err) + } + + spawn("gRPC server", func() { + err = s.server.Serve(lis) + if err != nil { + fmt.Printf("%+v", err) + } + }) + + + return nil +} + +func (s *grpcServer) Stop() { + s.server.Stop() + s.server = nil +} + +func (s *grpcServer) GetPeersList(ctx context.Context, req *pb2.GetPeersListRequest) (*pb2.GetPeersListResponse, error) { + + subnetworkID, err := FromProtobufSubnetworkID(req.SubnetworkID) + + if err != nil { + return nil, err + } + + // mb, we should move DNS-related logic out of manager? + ipv4Addresses := s.amgr.GoodAddresses(dns.TypeA, wire.ServiceFlag(req.ServiceFlag), req.IncludeAllSubnetworks, subnetworkID) + ipv6Addresses := s.amgr.GoodAddresses(dns.TypeAAAA, wire.ServiceFlag(req.ServiceFlag), req.IncludeAllSubnetworks, subnetworkID) + + addresses := ToProtobufAddresses(append(ipv4Addresses, ipv6Addresses...)) + log.Error("ADDRESSES: %+v", addresses) + + return &pb2.GetPeersListResponse{ Addresses: addresses}, nil +} + +func FromProtobufSubnetworkID(proto []byte) (*subnetworkid.SubnetworkID, error) { + if len(proto) == 0 { + return nil, nil + } + + subnetworkID, err := subnetworkid.New(proto) + if err != nil { + return nil, err + } + + return subnetworkID, nil +} + +func ToProtobufAddresses(addresses []*wire.NetAddress) []*pb2.NetAddress { + var protoAddresses []*pb2.NetAddress + + for _, addr := range addresses { + proto := &pb2.NetAddress{ + Timestamp: addr.Timestamp.UnixSeconds(), + Services: uint64(addr.Services), + IP: []byte(addr.IP), + Port: uint32(addr.Port), + } + protoAddresses = append(protoAddresses, proto) + } + + return protoAddresses +} \ No newline at end of file diff --git a/grpc_test.go b/grpc_test.go new file mode 100644 index 00000000..0f3d0ed6 --- /dev/null +++ b/grpc_test.go @@ -0,0 +1,99 @@ +package main + +import ( + "context" + "fmt" + pb2 "github.com/kaspanet/kaspad/dnsseed/pb" +"github.com/kaspanet/kaspad/util/subnetworkid" + "github.com/kaspanet/kaspad/wire" + "google.golang.org/grpc" + "net" + "os" + "testing" +) + +func TestGetPeers(t *testing.T) { + peersDefaultPort = 1313 + + var err error + amgr, err = NewManager(defaultHomeDir) + if err != nil { + fmt.Fprintf(os.Stderr, "NewManager: %v\n", err) + os.Exit(1) + } + + amgr.Good(net.IP([]byte{ 203, 105, 20, 21}), wire.SFNodeNetwork, &subnetworkid.SubnetworkID{}) + + grpcServer := NewGRPCServer(amgr) + err = grpcServer.Start(3737) + + if err != nil { + t.Fatal("Failed to start gRPC server") + } + + //defer func() { + // log.Infof("Gracefully shutting down the seeder...") + // atomic.StoreInt32(&systemShutdown, 1) + // close(amgr.quit) + // wg.Wait() + // amgr.wg.Wait() + // log.Infof("Seeder shutdown complete") + //}() + + + host := "localhost:3737" + var subnetworkID *subnetworkid.SubnetworkID = &subnetworkid.SubnetworkID{} + + conn, err := grpc.Dial(host, grpc.WithInsecure()) + client := pb2.NewPeerServiceClient(conn) + serviceFlag := wire.SFNodeNetwork + includeAllSubnetworks := false + if err != nil { + t.Logf("Failed to connect to gRPC server: %s", host) + } + + var subnetID []byte + if subnetworkID != nil { + subnetID = subnetworkID.CloneBytes() + } else { + subnetID = nil + } + + req := &pb2.GetPeersListRequest{ + ServiceFlag: uint64(serviceFlag), + SubnetworkID: subnetID, + IncludeAllSubnetworks: includeAllSubnetworks, + } + t.Error() + res, err := client.GetPeersList(context.Background(), req) + + + if err != nil { + t.Errorf("gRPC request to get peers failed (host=%s): %s", host, err) + return + } + + seedPeers := fromProtobufAddresses(res.Addresses) + + numPeers := len(seedPeers) + + t.Logf("%d addresses found from DNS seed %s", numPeers, host) + + if numPeers == 0 { + t.Error("No peers") + } + + t.Logf("finally") + grpcServer.Stop() +} + +func fromProtobufAddresses(proto []*pb2.NetAddress) []net.IP { + var addresses []net.IP + + + for _, pbAddr := range proto { + addresses = append(addresses, net.IP(pbAddr.IP)) + } + + return addresses +} diff --git a/test.sh b/test.sh new file mode 100755 index 00000000..54070512 --- /dev/null +++ b/test.sh @@ -0,0 +1,45 @@ +#!/bin/bash +GOPATH=${GOPATH:-$HOME/go} +KASPAD_PKG="github.com/kaspanet/kaspad" +KASPAD_DIR="$GOPATH/src/$KASPAD_PKG" +SEEDER_DIR=$PWD +BRANCH=$(git branch --show-current) + +echo $KASPAD_DIR + +set -e + +if [ ! -d "$KASPAD_DIR" ]; then + git clone $KASPAD_PKG +fi + +cd $KASPAD_DIR +git checkout $BRANCH +go build +./kaspad --datadir=$SEEDER_DIR/testdata/kaspad1 --allowlocalpeers --notls --rpcuser=test --rpcpass=test --listen=127.0.0.1:16621 --rpclisten=127.0.0.1:16620 --devnet --grpcseed=127.0.0.1:3737 & +KASPAD1_PID=$! +cd - +sleep 1 + +go build +./dnsseeder -n test.com -H test.com -s 127.0.0.1 --devnet -p "127.0.0.1:16621" & +SEEDER_PID=$! +sleep 3 + +cd $KASPAD_DIR +./kaspad --datadir=$SEEDER_DIR/testdata/kaspad2 --allowlocalpeers --notls --rpcuser=test --rpcpass=test --listen=127.0.0.1:16631 --rpclisten=127.0.0.1:16630 --devnet --grpcseed=127.0.0.1:3737 & +KASPAD2_PID=$! +cd - +sleep 2 + +RESULT=$(go run cmd/get_peers_list.go) +EXPECTED="127.0.0.1:16621,127.0.0.1:16611" + +sleep 2 +kill $KASPAD1_PID $KASPAD2_PID $SEEDER_PID +rm -rf testdata + +if [ $RESULT != $EXPECTED ]; then + echo "Test failed: Unexpected list addresses: " $RESULT + exit 1 +fi \ No newline at end of file