From 86aa1c16e60d84d7f1a8703496f8c01dde1b3c19 Mon Sep 17 00:00:00 2001 From: Ian Norden Date: Fri, 9 Apr 2021 09:50:46 -0500 Subject: [PATCH] support net endpoints --- cmd/serve.go | 2 +- pkg/eth/api.go | 1 + pkg/eth/eth_suite_test.go | 2 +- pkg/net/api.go | 79 +++++++++++++++++++++++++++++++++++++++ pkg/net/api_test.go | 47 +++++++++++++++++++++++ pkg/net/net_suite_test.go | 35 +++++++++++++++++ pkg/serve/api.go | 31 --------------- pkg/serve/service.go | 23 ++++-------- 8 files changed, 171 insertions(+), 49 deletions(-) create mode 100644 pkg/net/api.go create mode 100644 pkg/net/api_test.go create mode 100644 pkg/net/net_suite_test.go diff --git a/cmd/serve.go b/cmd/serve.go index f539b218..a495c126 100644 --- a/cmd/serve.go +++ b/cmd/serve.go @@ -98,7 +98,7 @@ func startServers(server s.Server, settings *s.Config) error { return err } logWithCommand.Info("starting up HTTP server") - _, err = srpc.StartHTTPEndpoint(settings.HTTPEndpoint, server.APIs(), []string{"eth"}, nil, []string{"*"}, rpc.HTTPTimeouts{}) + _, err = srpc.StartHTTPEndpoint(settings.HTTPEndpoint, server.APIs(), []string{"eth", "net"}, nil, []string{"*"}, rpc.HTTPTimeouts{}) return err } diff --git a/pkg/eth/api.go b/pkg/eth/api.go index 9b462e3a..257b0bd7 100644 --- a/pkg/eth/api.go +++ b/pkg/eth/api.go @@ -48,6 +48,7 @@ const APIName = "eth" // APIVersion is the version of the watcher's eth api const APIVersion = "0.0.1" +// PublicEthAPI is the eth namespace API type PublicEthAPI struct { // Local db backend B *Backend diff --git a/pkg/eth/eth_suite_test.go b/pkg/eth/eth_suite_test.go index 3be0ebfc..73dabe49 100644 --- a/pkg/eth/eth_suite_test.go +++ b/pkg/eth/eth_suite_test.go @@ -25,7 +25,7 @@ import ( "github.com/sirupsen/logrus" ) -func TestETHWatcher(t *testing.T) { +func TestETHSuite(t *testing.T) { RegisterFailHandler(Fail) RunSpecs(t, "eth ipld server eth suite test") } diff --git a/pkg/net/api.go b/pkg/net/api.go new file mode 100644 index 00000000..13178c8f --- /dev/null +++ b/pkg/net/api.go @@ -0,0 +1,79 @@ +// VulcanizeDB +// Copyright © 2021 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package net + +import ( + "fmt" + + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/ethereum/go-ethereum/rpc" +) + +// APIName is the namespace for the watcher's eth api +const APIName = "net" + +// APIVersion is the version of the watcher's eth api +const APIVersion = "0.0.1" + +// PublicNetAPI is the net nampespace API +type PublicNetAPI struct { + // Proxy node for forwarding cache misses + networkVersion uint64 + rpc *rpc.Client + ethClient *ethclient.Client +} + +// NewPublicNetAPI creates a new PublicNetAPI with the provided underlying Backend +func NewPublicNetAPI(networkID uint64, client *rpc.Client) *PublicNetAPI { + var ethClient *ethclient.Client + if client != nil { + ethClient = ethclient.NewClient(client) + } + return &PublicNetAPI{ + networkVersion: networkID, + rpc: client, + ethClient: ethClient, + } +} + +// Listening returns an indication if the node is listening for network connections. +func (pna *PublicNetAPI) Listening() bool { + return false // currently our nodes are never listening on the p2p network +} + +// PeerCount returns the number of connected peers +func (pna *PublicNetAPI) PeerCount() hexutil.Uint { + num := new(hexutil.Uint) + // in this case it is actually the peercount of the proxied node + if err := pna.rpc.Call(num, "net_peerCount"); num != nil && err == nil { + return *num + } + return hexutil.Uint(0) +} + +// Version returns the current ethereum protocol version. +func (pna *PublicNetAPI) Version() string { + if pna.networkVersion != 0 { + return fmt.Sprintf("%d", pna.networkVersion) + } + version := new(string) + if err := pna.rpc.Call(version, "net_version"); version != nil && err == nil { + return *version + } + return "" +} diff --git a/pkg/net/api_test.go b/pkg/net/api_test.go new file mode 100644 index 00000000..3f780a8d --- /dev/null +++ b/pkg/net/api_test.go @@ -0,0 +1,47 @@ +// VulcanizeDB +// Copyright © 2021 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package net_test + +import ( + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + + "github.com/vulcanize/ipld-eth-server/pkg/net" +) + +var _ = Describe("API", func() { + var ( + api *net.PublicNetAPI + ) + BeforeEach(func() { + api = net.NewPublicNetAPI(1, nil) + }) + Describe("net_listening", func() { + It("Retrieves whether or not the node is listening to the p2p network", func() { + listening := api.Listening() + Expect(listening).To(BeFalse()) + }) + }) + + Describe("net_version", func() { + It("Retrieves the network id", func() { + version := api.Version() + Expect(version).To(Equal("1")) + }) + }) + // TODO: test PeerCount and proxying +}) diff --git a/pkg/net/net_suite_test.go b/pkg/net/net_suite_test.go new file mode 100644 index 00000000..aa2b5b8b --- /dev/null +++ b/pkg/net/net_suite_test.go @@ -0,0 +1,35 @@ +// VulcanizeDB +// Copyright © 2021 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package net_test + +import ( + "io/ioutil" + "testing" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + "github.com/sirupsen/logrus" +) + +func TestNetSuite(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "eth ipld server net suite test") +} + +var _ = BeforeSuite(func() { + logrus.SetOutput(ioutil.Discard) +}) diff --git a/pkg/serve/api.go b/pkg/serve/api.go index 23a8a88c..cbf0abaa 100644 --- a/pkg/serve/api.go +++ b/pkg/serve/api.go @@ -19,14 +19,12 @@ package serve import ( "context" - "github.com/ethereum/go-ethereum/p2p" "github.com/ethereum/go-ethereum/rpc" log "github.com/sirupsen/logrus" "github.com/vulcanize/ipld-eth-indexer/pkg/shared" "github.com/vulcanize/ipld-eth-server/pkg/eth" - v "github.com/vulcanize/ipld-eth-server/version" ) // APIName is the namespace used for the state diffing service API @@ -90,32 +88,3 @@ func (api *PublicServerAPI) Stream(ctx context.Context, params eth.SubscriptionS func (api *PublicServerAPI) Chain() shared.ChainType { return shared.Ethereum } - -// Struct for holding watcher meta data -type InfoAPI struct{} - -// NewInfoAPI creates a new InfoAPI -func NewInfoAPI() *InfoAPI { - return &InfoAPI{} -} - -// Modules returns modules supported by this api -func (iapi *InfoAPI) Modules() map[string]string { - return map[string]string{ - "vdb": "Stream", - } -} - -// NodeInfo gathers and returns a collection of metadata for the watcher -func (iapi *InfoAPI) NodeInfo() *p2p.NodeInfo { - return &p2p.NodeInfo{ - // TODO: formalize this - ID: "vulcanizeDB", - Name: "ipld-eth-server", - } -} - -// Version returns the version of the watcher -func (iapi *InfoAPI) Version() string { - return v.VersionWithMeta -} diff --git a/pkg/serve/service.go b/pkg/serve/service.go index 0ca5b2c5..c5f30b47 100644 --- a/pkg/serve/service.go +++ b/pkg/serve/service.go @@ -18,8 +18,11 @@ package serve import ( "fmt" + "strconv" "sync" + "github.com/vulcanize/ipld-eth-server/pkg/net" + "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/common" @@ -115,7 +118,7 @@ func (sap *Service) Protocols() []p2p.Protocol { // APIs returns the RPC descriptors the watcher service offers func (sap *Service) APIs() []rpc.API { - infoAPI := NewInfoAPI() + networkID, _ := strconv.ParseUint(sap.db.Node.NetworkID, 10, 64) apis := []rpc.API{ { Namespace: APIName, @@ -124,21 +127,9 @@ func (sap *Service) APIs() []rpc.API { Public: true, }, { - Namespace: "rpc", - Version: APIVersion, - Service: infoAPI, - Public: true, - }, - { - Namespace: "net", - Version: APIVersion, - Service: infoAPI, - Public: true, - }, - { - Namespace: "admin", - Version: APIVersion, - Service: infoAPI, + Namespace: net.APIName, + Version: net.APIVersion, + Service: net.NewPublicNetAPI(networkID, sap.client), Public: true, }, }