Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix issues identified during testing #31

Merged
merged 6 commits into from
Feb 28, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ APP_NAME = faultdetector
GREEN = \033[1;32m
BLUE = \033[1;34m
COLOR_END = \033[0;39m
CONFIG_PATH = $(realpath $(config))

build: # Builds the application and create a binary at ./bin/
@echo "$(BLUE)» Building fault detector application binary... $(COLOR_END)"
Expand Down Expand Up @@ -61,15 +62,19 @@ docker-run: # Runs docker image, use `make docker-run config={PATH_TO_CONFIG_FIL
ifdef config
nagdahimanshu marked this conversation as resolved.
Show resolved Hide resolved
@echo "$(BLUE) Running docker image...$(COLOR_END)"
ifdef slack_access_token
@docker run -p 8080:8080 -v $(config):/home/onchain/faultdetector/config.yaml -t -e SLACK_ACCESS_TOKEN_KEY=$(slack_access_token) $(APP_NAME)
@docker run --name $(APP_NAME) -p 8080:8080 -d -v $(CONFIG_PATH):/home/onchain/faultdetector/config.yaml -t -e SLACK_ACCESS_TOKEN_KEY=$(slack_access_token) $(APP_NAME)
else
@docker run -p 8080:8080 -v $(config):/home/onchain/faultdetector/config.yaml -t $(APP_NAME)
@docker run --name $(APP_NAME) -p 8080:8080 -d -v $(CONFIG_PATH):/home/onchain/faultdetector/config.yaml -t $(APP_NAME)
endif
else
@echo "$(BLUE) Running docker image...$(COLOR_END)"
@docker run -p 8080:8080 $(APP_NAME)
@docker run --name $(APP_NAME) -p 8080:8080 -d $(APP_NAME)
endif

docker-stop:
@echo "$(BLUE) Stopping and removing docker container $(APP_NAME)...$(COLOR_END)"
@docker rm -f $(APP_NAME)

.PHONY: help
help: # Show help for each of the Makefile recipes
@grep -E '^[a-zA-Z0-9 -]+:.*#' Makefile | sort | while read -r l; do printf "$(GREEN)$$(echo $$l | cut -f 1 -d':')$(COLOR_END):$$(echo $$l | cut -f 2- -d'#')\n"; done
15 changes: 8 additions & 7 deletions cmd/faultdetector/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ func NewApp(ctx context.Context, logger log.Logger) (*App, error) {
flag.Parse()
config, err := getAppConfig(logger, *configFilepath)
if err != nil {
logger.Errorf("Failed at parsing config with error %w", err)
logger.Errorf("Failed at parsing config with error %v", err)
return nil, err
}

Expand All @@ -66,7 +66,7 @@ func NewApp(ctx context.Context, logger log.Logger) (*App, error) {
config.Notification,
)
if err != nil {
logger.Errorf("Failed to initialize notification service, error: %w", err)
logger.Errorf("Failed to initialize notification service, error: %v", err)
return nil, err
}
}
Expand Down Expand Up @@ -114,6 +114,7 @@ func (app *App) Start() {
app.wg.Add(1)
go app.faultDetector.Start()

app.apiServer.RegisterHandlersForVersion(app.faultDetector, app.config.Api.RegisterVersions, app.config.Api.BasePath)
sameersubudhi marked this conversation as resolved.
Show resolved Hide resolved
app.wg.Add(1)
go app.apiServer.Start()

Expand All @@ -136,7 +137,7 @@ func (app *App) Start() {
app.logger.Errorf("Received error of %v", err)
if app.notification != nil {
if err := app.notification.Notify("Error while starting application"); err != nil {
app.logger.Errorf("Failed to send notification, error: %w", err)
app.logger.Errorf("Failed to send notification, error: %v", err)
}
}
return
Expand All @@ -148,7 +149,7 @@ func (app *App) stop() {
app.faultDetector.Stop()
err := app.apiServer.Stop()
if err != nil {
app.logger.Error("Server shutdown not successful: %w", err)
app.logger.Error("Server shutdown not successful: %v", err)
}
}

Expand All @@ -158,13 +159,13 @@ func main() {

logger, err := log.NewDefaultProductionLogger()
if err != nil {
logger.Errorf("Failed to create logger, %w", err)
logger.Errorf("Failed to create logger, %v", err)
return
}

app, err := NewApp(ctx, logger)
if err != nil {
logger.Errorf("Failed to create app, %w", err)
logger.Errorf("Failed to create app, %v", err)
return
}

Expand All @@ -180,10 +181,10 @@ func getAppConfig(logger log.Logger, configFilepath string) (*config.Config, err
splits := strings.FieldsFunc(configFilenameWithExt, func(r rune) bool { return r == '.' })
configType := splits[len(splits)-1] // Config file extension

viper.AddConfigPath(configDir)
viper.AddConfigPath(".")
viper.AddConfigPath("..")
viper.AddConfigPath("$HOME/.op-fault-detector")
viper.AddConfigPath(configDir)
viper.SetConfigName(configFilenameWithExt)
viper.SetConfigType(configType)
err := viper.ReadInConfig()
Expand Down
3 changes: 2 additions & 1 deletion cmd/faultdetector/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ func prepareFaultDetector(t *testing.T, ctx context.Context, logger log.Logger,
if !mock {
fd, _ = faultdetector.NewFaultDetector(ctx, logger, erroChan, wg, config.FaultDetectorConfig, reg, testNotificationService)
} else {
mx := new(sync.RWMutex)
metrics := faultdetector.NewFaultDetectorMetrics(reg)

// Create chain API clients
Expand Down Expand Up @@ -136,7 +137,7 @@ func prepareFaultDetector(t *testing.T, ctx context.Context, logger log.Logger,
L2OutputIndex: 2,
}, nil)

fd = faultdetector.GetFaultDetector(ctx, logger, l1RpcApi, l2RpcApi, oracle, faultProofWindow, currentOutputIndex, metrics, testNotificationService, false, wg, erroChan)
fd = faultdetector.GetFaultDetector(ctx, logger, l1RpcApi, l2RpcApi, oracle, faultProofWindow, currentOutputIndex, metrics, testNotificationService, false, wg, erroChan, mx)
}

return fd
Expand Down
7 changes: 3 additions & 4 deletions pkg/api/handlers/v1/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,13 @@ import (
)

type statusResponse struct {
Status string `json:"status"`
Ok bool `json:"ok"`
sameersubudhi marked this conversation as resolved.
Show resolved Hide resolved
}

// GetStatus is the handler for the 'GET /api/v1/status' endpoint.
func GetStatus(c *gin.Context) {
func GetStatus(c *gin.Context, isFaultDetected bool) {
status := statusResponse{
Status: "ok",
Ok: !isFaultDetected,
sameersubudhi marked this conversation as resolved.
Show resolved Hide resolved
}

c.IndentedJSON(http.StatusOK, status)
}
21 changes: 0 additions & 21 deletions pkg/api/routes/registration.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package routes

import (
"github.com/LiskHQ/op-fault-detector/pkg/api/handlers"
v1 "github.com/LiskHQ/op-fault-detector/pkg/api/handlers/v1"
"github.com/LiskHQ/op-fault-detector/pkg/log"
"github.com/gin-gonic/gin"
)
Expand All @@ -12,23 +11,3 @@ import (
func RegisterHandlers(logger log.Logger, router *gin.Engine) {
router.GET("/ping", handlers.GetPing)
}

// RegisterHandlersByGroup is responsible to register all the handlers for routes that are prefixed under a specified base path as a routerGroup.
func RegisterHandlersByGroup(logger log.Logger, routerGroup *gin.RouterGroup, versions []string) {
for _, version := range versions {
RegisterHandlersForVersion(logger, routerGroup, version)
}
}

// RegisterHandlersForVersion is responsible to register API version specific route handlers.
func RegisterHandlersForVersion(logger log.Logger, routerGroup *gin.RouterGroup, version string) {
group := routerGroup.Group(version)

switch version {
case "v1":
group.GET("/status", v1.GetStatus)

default:
logger.Warningf("No routes and handlers defined for version %s. Please verify the API config.", version)
}
}
32 changes: 26 additions & 6 deletions pkg/api/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,17 @@ import (
"sync"
"time"

v1 "github.com/LiskHQ/op-fault-detector/pkg/api/handlers/v1"
"github.com/LiskHQ/op-fault-detector/pkg/api/middlewares"
"github.com/LiskHQ/op-fault-detector/pkg/api/routes"
"github.com/LiskHQ/op-fault-detector/pkg/config"
"github.com/LiskHQ/op-fault-detector/pkg/faultdetector"
"github.com/LiskHQ/op-fault-detector/pkg/log"
"github.com/gin-gonic/gin"
)

var areVersionsHandlerRegistered bool = false

// HTTPServer embeds the http.Server along with the various other properties.
type HTTPServer struct {
server *http.Server
Expand All @@ -25,10 +29,32 @@ type HTTPServer struct {
errorChan chan error
}

// RegisterHandlersForVersion is responsible to register API version specific route handlers.
sameersubudhi marked this conversation as resolved.
Show resolved Hide resolved
func (w *HTTPServer) RegisterHandlersForVersion(fd *faultdetector.FaultDetector, versions []string, basePath string) {
nagdahimanshu marked this conversation as resolved.
Show resolved Hide resolved
baseGroup := w.router.Group(basePath)
for _, version := range versions {
group := baseGroup.Group(version)
switch version {
case "v1":
group.GET("/status", func(c *gin.Context) {
v1.GetStatus(c, fd.IsFaultDetected())
})

default:
w.logger.Warningf("No routes and handlers defined for version %s. Please verify the API config.", version)
}
}
areVersionsHandlerRegistered = true
sameersubudhi marked this conversation as resolved.
Show resolved Hide resolved
}

// Start starts the HTTP API server.
func (w *HTTPServer) Start() {
defer w.wg.Done()

if !areVersionsHandlerRegistered {
w.errorChan <- fmt.Errorf("API specific versions handler are not registered")
}

w.logger.Infof("Starting the HTTP server on %s.", w.server.Addr)
err := w.server.ListenAndServe()
if err != nil {
Expand Down Expand Up @@ -74,12 +100,6 @@ func NewHTTPServer(ctx context.Context, logger log.Logger, wg *sync.WaitGroup, c

routes.RegisterHandlers(logger, router)

// Register handlers for routes following the base path
basePath := config.Api.BasePath
baseGroup := router.Group(basePath)
logger.Debugf("Registering handlers for endpoints under path '%s'.", basePath)
routes.RegisterHandlersByGroup(logger, baseGroup, config.Api.RegisterVersions)

host := config.Api.Server.Host
port := config.Api.Server.Port
addr := fmt.Sprintf("%s:%d", host, port)
Expand Down
2 changes: 1 addition & 1 deletion pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (

var (
providerEndpointRegex = regexp.MustCompile(`^(http|https|ws|wss)://`)
addressRegex = regexp.MustCompile(`(\b0x[a-f0-9]{40}\b)`)
addressRegex = regexp.MustCompile(`(\b0x[A-Fa-f0-9]{40}\b)`)
hostRegex = regexp.MustCompile(`^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$`)
basePathRegex = regexp.MustCompile(`^/?api$`)
registerVersionRegex = regexp.MustCompile(`^v[1-9]\d*$`)
Expand Down
Loading
Loading