diff --git a/cmd/proxy.go b/cmd/proxy.go deleted file mode 100644 index a1323e57..00000000 --- a/cmd/proxy.go +++ /dev/null @@ -1,125 +0,0 @@ -package cmd - -import ( - "errors" - "fmt" - "net/http" - "net/url" - "strings" - - "github.com/ethereum/go-ethereum/rpc" - "github.com/sirupsen/logrus" - "github.com/spf13/cobra" - "github.com/spf13/viper" - "github.com/vulcanize/gap-filler/pkg/mux" -) - -var ErrNoRpcEndpoints = errors.New("no rpc endpoints is available") - -// proxyCmd represents the proxy command -var proxyCmd = &cobra.Command{ - Use: "proxy", - Short: "serve chain data from PG-IPFS or proxy geths", - Long: `This command configures a VulcanizeDB ipld-eth-server graphql server. - -`, - Run: func(cmd *cobra.Command, args []string) { - subCommand = cmd.CalledAs() - logWithCommand = *logrus.WithField("SubCommand", subCommand) - proxy() - }, -} - -func proxy() { - gqlDefaultAddr, err := url.Parse(viper.GetString("gql.default")) - if err != nil { - logWithCommand.Fatal(err) - } - - gqlTracingAPIAddr, err := url.Parse(viper.GetString("gql.tracing")) - if err != nil { - logWithCommand.Fatal(err) - } - - rpcClients, err := parseRpcAddresses(viper.GetString("rpc.eth")) - if err != nil { - logrus.Error("bad rpc.eth addresses") - logWithCommand.Fatal(err) - } - - tracingClients, err := parseRpcAddresses(viper.GetString("rpc.tracing")) - if err != nil { - logrus.Error("bad rpc.tracing addresses") - logWithCommand.Fatal(err) - } - - router, err := mux.NewServeMux(&mux.Options{ - BasePath: viper.GetString("http.path"), - EnableGraphiQL: viper.GetBool("gql.gui"), - Postgraphile: mux.PostgraphileOptions{ - Default: gqlDefaultAddr, - TracingAPI: gqlTracingAPIAddr, - }, - RPC: mux.RPCOptions{ - DefaultClients: rpcClients, - TracingClients: tracingClients, - }, - }) - if err != nil { - logWithCommand.Fatal(err) - } - - addr := fmt.Sprintf("%s:%s", viper.GetString("http.host"), viper.GetString("http.port")) - if err := http.ListenAndServe(addr, router); err != nil { - logWithCommand.Fatal(err) - } -} - -func parseRpcAddresses(value string) ([]*rpc.Client, error) { - rpcAddresses := strings.Split(value, ",") - rpcClients := make([]*rpc.Client, 0, len(rpcAddresses)) - for _, address := range rpcAddresses { - rpcClient, err := rpc.Dial(address) - if err != nil { - logWithCommand.Errorf("couldn't connect to %s. Error: %s", address, err) - continue - } - - rpcClients = append(rpcClients, rpcClient) - } - - if len(rpcClients) == 0 { - logWithCommand.Error(ErrNoRpcEndpoints) - return nil, ErrNoRpcEndpoints - } - - return rpcClients, nil -} - -func init() { - rootCmd.AddCommand(proxyCmd) - - // flags - proxyCmd.PersistentFlags().String("http-host", "127.0.0.1", "http host") - proxyCmd.PersistentFlags().String("http-port", "8083", "http port") - proxyCmd.PersistentFlags().String("http-path", "/", "http base path") - - proxyCmd.PersistentFlags().String("rpc-eth", "http://127.0.0.1:8545", "comma separated ethereum rpc addresses. Example http://127.0.0.1:8545,http://127.0.0.2:8545") - proxyCmd.PersistentFlags().String("rpc-tracing", "http://127.0.0.1:8000", "comma separated traicing api addresses") - - proxyCmd.PersistentFlags().String("gql-default", "http://127.0.0.1:5020/graphql", "postgraphile address") - proxyCmd.PersistentFlags().String("gql-tracing", "http://127.0.0.1:5020/graphql", "tracing api postgraphile address") - proxyCmd.PersistentFlags().Bool("gql-gui", false, "enable graphiql interface") - - // and their .toml config bindings - viper.BindPFlag("http.host", proxyCmd.PersistentFlags().Lookup("http-host")) - viper.BindPFlag("http.port", proxyCmd.PersistentFlags().Lookup("http-port")) - viper.BindPFlag("http.path", proxyCmd.PersistentFlags().Lookup("http-path")) - - viper.BindPFlag("rpc.eth", proxyCmd.PersistentFlags().Lookup("rpc-eth")) - viper.BindPFlag("rpc.tracing", proxyCmd.PersistentFlags().Lookup("rpc-tracing")) - - viper.BindPFlag("gql.default", proxyCmd.PersistentFlags().Lookup("gql-default")) - viper.BindPFlag("gql.tracing", proxyCmd.PersistentFlags().Lookup("gql-tracing")) - viper.BindPFlag("gql.gui", proxyCmd.PersistentFlags().Lookup("gql-gui")) -} diff --git a/cmd/serve.go b/cmd/serve.go index 7df69c42..760b53cb 100644 --- a/cmd/serve.go +++ b/cmd/serve.go @@ -16,11 +16,13 @@ package cmd import ( + "errors" "github.com/vulcanize/gap-filler/pkg/mux" "net/http" "net/url" "os" "os/signal" + "strings" "sync" "github.com/vulcanize/ipld-eth-server/pkg/graphql" @@ -37,6 +39,8 @@ import ( v "github.com/vulcanize/ipld-eth-server/version" ) +var ErrNoRpcEndpoints = errors.New("no rpc endpoints is available") + // serveCmd represents the serve command var serveCmd = &cobra.Command{ Use: "serve", @@ -79,6 +83,11 @@ func serve() { logWithCommand.Fatal(err) } + err = startIpldGraphQL(serverConfig) + if err != nil { + logWithCommand.Fatal(err) + } + shutdown := make(chan os.Signal) signal.Notify(shutdown, os.Interrupt) <-shutdown @@ -191,6 +200,27 @@ func startIpldGraphQL(settings *s.Config) error { return nil } +func parseRpcAddresses(value string) ([]*rpc.Client, error) { + rpcAddresses := strings.Split(value, ",") + rpcClients := make([]*rpc.Client, 0, len(rpcAddresses)) + for _, address := range rpcAddresses { + rpcClient, err := rpc.Dial(address) + if err != nil { + logWithCommand.Errorf("couldn't connect to %s. Error: %s", address, err) + continue + } + + rpcClients = append(rpcClients, rpcClient) + } + + if len(rpcClients) == 0 { + logWithCommand.Error(ErrNoRpcEndpoints) + return nil, ErrNoRpcEndpoints + } + + return rpcClients, nil +} + func init() { rootCmd.AddCommand(serveCmd) @@ -232,11 +262,11 @@ func init() { // and their bindings // database - viper.BindPFlag("database.name", rootCmd.PersistentFlags().Lookup("database-name")) - viper.BindPFlag("database.port", rootCmd.PersistentFlags().Lookup("database-port")) - viper.BindPFlag("database.hostname", rootCmd.PersistentFlags().Lookup("database-hostname")) - viper.BindPFlag("database.user", rootCmd.PersistentFlags().Lookup("database-user")) - viper.BindPFlag("database.password", rootCmd.PersistentFlags().Lookup("database-password")) + viper.BindPFlag("database.name", serveCmd.PersistentFlags().Lookup("database-name")) + viper.BindPFlag("database.port", serveCmd.PersistentFlags().Lookup("database-port")) + viper.BindPFlag("database.hostname", serveCmd.PersistentFlags().Lookup("database-hostname")) + viper.BindPFlag("database.user", serveCmd.PersistentFlags().Lookup("database-user")) + viper.BindPFlag("database.password", serveCmd.PersistentFlags().Lookup("database-password")) // eth graphql server viper.BindPFlag("eth.server.graphql", serveCmd.PersistentFlags().Lookup("eth-server-graphql")) diff --git a/docker-compose.yml b/docker-compose.yml index 03942091..7e98d2c2 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -3,11 +3,31 @@ version: '3.2' services: dapptools: restart: unless-stopped - image: vulcanize/dapptools:v0.29.0-statediff-0.0.2 + depends_on: + - statediff-migrations + image: vulcanize/dapptools:v0.29.0-v1.10.2-statediff-0.0.19 + environment: + DB_USER: vdbm + DB_NAME: vulcanize_public + DB_HOST: db + DB_PORT: 5432 + DB_PASSWORD: password ports: - "127.0.0.1:8545:8545" - "127.0.0.1:8546:8546" + statediff-migrations: + restart: on-failure + depends_on: + - db + image: vulcanize/statediff-migrations:v0.3.0 + environment: + DATABASE_USER: vdbm + DATABASE_NAME: vulcanize_public + DATABASE_HOSTNAME: db + DATABASE_PORT: 5432 + DATABASE_PASSWORD: password + db: restart: always image: postgres:10.12-alpine @@ -20,24 +40,6 @@ services: ports: - "127.0.0.1:8077:5432" - eth-indexer: - restart: unless-stopped - depends_on: - - db - - dapptools - image: vulcanize/ipld-eth-indexer:v0.3.0-alpha - environment: - DATABASE_NAME: vulcanize_public - DATABASE_HOSTNAME: db - DATABASE_PORT: 5432 - DATABASE_USER: vdbm - DATABASE_PASSWORD: password - ETH_WS_PATH: "dapptools:8546" - ETH_HTTP_PATH: "dapptools:8545" - ETH_CHAIN_ID: 4 - ETH_NETWORK_ID: 4 - VDB_COMMAND: sync - eth-server: depends_on: - db diff --git a/pkg/eth/backend.go b/pkg/eth/backend.go index 2be41efc..1419b790 100644 --- a/pkg/eth/backend.go +++ b/pkg/eth/backend.go @@ -174,7 +174,11 @@ func (b *Backend) HeaderByNumberOrHash(ctx context.Context, blockNrOrHash rpc.Bl if header == nil { return nil, errors.New("header for hash not found") } - if blockNrOrHash.RequireCanonical && b.GetCanonicalHash(header.Number.Uint64()) != hash { + canonicalHash, err := b.GetCanonicalHash(header.Number.Uint64()) + if err != nil { + return nil, err + } + if blockNrOrHash.RequireCanonical && canonicalHash != hash { return nil, errors.New("hash is not currently canonical") } return header, nil @@ -215,7 +219,11 @@ func (b *Backend) BlockByNumberOrHash(ctx context.Context, blockNrOrHash rpc.Blo if header == nil { return nil, errors.New("header for hash not found") } - if blockNrOrHash.RequireCanonical && b.GetCanonicalHash(header.Number.Uint64()) != hash { + canonicalHash, err := b.GetCanonicalHash(header.Number.Uint64()) + if err != nil { + return nil, err + } + if blockNrOrHash.RequireCanonical && canonicalHash != hash { return nil, errors.New("hash is not currently canonical") } block, err := b.BlockByHash(ctx, hash) @@ -253,7 +261,7 @@ func (b *Backend) BlockByNumber(ctx context.Context, blockNumber rpc.BlockNumber return nil, errNegativeBlockNumber } // Get the canonical hash - canonicalHash := b.GetCanonicalHash(uint64(number)) + canonicalHash, err := b.GetCanonicalHash(uint64(number)) if err != nil { return nil, err } @@ -475,7 +483,11 @@ func (b *Backend) StateAndHeaderByNumberOrHash(ctx context.Context, blockNrOrHas if header == nil { return nil, nil, errors.New("header for hash not found") } - if blockNrOrHash.RequireCanonical && b.GetCanonicalHash(header.Number.Uint64()) != hash { + canonicalHash, err := b.GetCanonicalHash(header.Number.Uint64()) + if err != nil { + return nil, nil, err + } + if blockNrOrHash.RequireCanonical && canonicalHash != hash { return nil, nil, errors.New("hash is not currently canonical") } stateDb, err := state.New(header.Root, b.StateDatabase, nil) @@ -503,12 +515,12 @@ func (b *Backend) StateAndHeaderByNumber(ctx context.Context, number rpc.BlockNu } // GetCanonicalHash gets the canonical hash for the provided number, if there is one -func (b *Backend) GetCanonicalHash(number uint64) common.Hash { +func (b *Backend) GetCanonicalHash(number uint64) (common.Hash, error) { var hashResult string if err := b.DB.Get(&hashResult, RetrieveCanonicalBlockHashByNumber, number); err != nil { - return common.Hash{} + return common.Hash{}, err } - return common.HexToHash(hashResult) + return common.HexToHash(hashResult), nil } type rowResult struct { @@ -543,7 +555,10 @@ func (b *Backend) GetAccountByNumberOrHash(ctx context.Context, address common.A // GetAccountByNumber returns the account object for the provided address at the canonical block at the provided height func (b *Backend) GetAccountByNumber(ctx context.Context, address common.Address, number uint64) (*state.Account, error) { - hash := b.GetCanonicalHash(number) + hash, err := b.GetCanonicalHash(number) + if err != nil { + return nil, err + } if hash == (common.Hash{}) { return nil, fmt.Errorf("no canoncial block hash found for provided height (%d)", number) } @@ -573,7 +588,10 @@ func (b *Backend) GetCodeByNumberOrHash(ctx context.Context, address common.Addr // GetCodeByNumber returns the byte code for the contract deployed at the provided address at the canonical block with the provided block number func (b *Backend) GetCodeByNumber(ctx context.Context, address common.Address, number uint64) ([]byte, error) { - hash := b.GetCanonicalHash(number) + hash, err := b.GetCanonicalHash(number) + if err != nil { + return nil, err + } if hash == (common.Hash{}) { return nil, fmt.Errorf("no canoncial block hash found for provided height (%d)", number) } @@ -624,7 +642,10 @@ func (b *Backend) GetStorageByNumberOrHash(ctx context.Context, address common.A // GetStorageByNumber returns the storage value for the provided contract address an storage key at the block corresponding to the provided number func (b *Backend) GetStorageByNumber(ctx context.Context, address common.Address, storageLeafKey common.Hash, number uint64) (hexutil.Bytes, error) { - hash := b.GetCanonicalHash(number) + hash, err := b.GetCanonicalHash(number) + if err != nil { + return nil, err + } if hash == (common.Hash{}) { return nil, fmt.Errorf("no canoncial block hash found for provided height (%d)", number) } diff --git a/pkg/rpc/http.go b/pkg/rpc/http.go index c8a0230d..bfde02c6 100644 --- a/pkg/rpc/http.go +++ b/pkg/rpc/http.go @@ -41,7 +41,7 @@ func StartHTTPEndpoint(endpoint string, apis []rpc.API, modules []string, cors [ utils.Fatalf("Could not start RPC api: %v", err) } extapiURL := fmt.Sprintf("http://%v/", addr) - log.Info("HTTP endpoint opened", "url", extapiURL) + log.Infof("HTTP endpoint opened %s", extapiURL) return srv, err }