package boot import ( "fmt" "net/http" "strconv" log "github.com/sirupsen/logrus" "github.com/vulcanize/ipld-ethcl-indexer/pkg/database/sql/postgres" "github.com/vulcanize/ipld-ethcl-indexer/pkg/loghelper" ) var ( bcHealthEndpoint = "/eth/v1/node/health" ) // This function will ensure that we can connect to the beacon client. // Keep in mind, the beacon client will allow you to connect to it but it might // Not allow you to make http requests. This is part of its built in logic, and you will have // to follow their provided guidelines. https://lighthouse-book.sigmaprime.io/api-bn.html#security func checkBeaconClient(bcAddress string, bcPort int) error { log.Debug("Attempting to connect to the beacon client") bcEndpoint := "http://" + bcAddress + ":" + strconv.Itoa(bcPort) + bcHealthEndpoint resp, err := http.Get(bcEndpoint) if err != nil { loghelper.LogError(err).Error("Unable to get bc endpoint: ", bcEndpoint) return err } if resp.StatusCode < 200 || resp.StatusCode > 299 { log.Error("We recieved a non 2xx status code when checking the health of the beacon node.") log.Error("Health Endpoint Status Code: ", resp.StatusCode) return fmt.Errorf("beacon Node Provided a non 2xx status code, code provided: %d", resp.StatusCode) } log.Info("We can successfully reach the beacon client.") return nil } // A simple wrapper to create a DB object to use. func SetupDb(dbHostname string, dbPort int, dbName string, dbUsername string, dbPassword string, driverName string) (*postgres.DB, error) { log.Debug("Resolving Driver Type") DbDriver, err := postgres.ResolveDriverType(driverName) if err != nil { log.WithFields(log.Fields{ "err": err, "driver_name_provided": driverName, }).Error("Can't resolve driver type") } log.Info("Using Driver:", DbDriver) postgresConfig := postgres.Config{ Hostname: dbHostname, Port: dbPort, DatabaseName: dbName, Username: dbUsername, Password: dbPassword, Driver: DbDriver, } DB, err := postgres.NewPostgresDB(postgresConfig) if err != nil { loghelper.LogError(err).Error("Unable to connect to the DB") return nil, err } return DB, err } // This function will perform some boot operations. If any steps fail, the application will fail to start. // Keep in mind that the DB connection can be lost later in the lifecycle of the application or // it might not be able to connect to the beacon client. // // 1. Make sure the Beacon client is up. // // 2. Connect to the database. // func BootApplication(dbHostname string, dbPort int, dbName string, dbUsername string, dbPassword string, driverName string, bcAddress string, bcPort int) (*postgres.DB, error) { log.Debug("Checking beacon Client") err := checkBeaconClient(bcAddress, bcPort) if err != nil { return nil, err } log.Debug("Setting up DB connection") DB, err := SetupDb(dbHostname, dbPort, dbName, dbUsername, dbPassword, driverName) if err != nil { return nil, err } return DB, nil }