Skip to content
Open
Show file tree
Hide file tree
Changes from 2 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
2 changes: 1 addition & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@ LOG_LEVEL=
METRICS_ENABLED=true
METRICS_HOST="[::]"
METRICS_PORT=4000
SHUTTER_EVENT_REGISTRY_CONTRACT_ADDRESS=
SHUTTER_EVENT_REGISTRY_CONTRACT_ADDRESS= # Event API is auto-disabled when this is empty
9 changes: 5 additions & 4 deletions common/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@ import (
)

type Config struct {
KeyperHTTPURL *url.URL
SigningKey *ecdsa.PrivateKey
PublicKey *ecdsa.PublicKey
P2P *p2p.Config
KeyperHTTPURL *url.URL
SigningKey *ecdsa.PrivateKey
PublicKey *ecdsa.PublicKey
P2P *p2p.Config
DisableEventAPI bool // true when SHUTTER_EVENT_REGISTRY_CONTRACT_ADDRESS is not configured; if true, event API endpoints are not registered
}

func NewConfig(keyperHTTPUrl string, signingKey *ecdsa.PrivateKey, p2pConfig *p2p.Config) (*Config, error) {
Expand Down
4 changes: 2 additions & 2 deletions docs/docs.go
Original file line number Diff line number Diff line change
Expand Up @@ -288,8 +288,8 @@ const docTemplate = `{
},
{
"type": "string",
"description": "Identity prefix associated with the event identity registration.",
"name": "identityPrefix",
"description": "Identity associated with the event identity registration.",
"name": "identity",
"in": "query",
"required": true
}
Expand Down
4 changes: 2 additions & 2 deletions docs/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -279,8 +279,8 @@
},
{
"type": "string",
"description": "Identity prefix associated with the event identity registration.",
"name": "identityPrefix",
"description": "Identity associated with the event identity registration.",
"name": "identity",
"in": "query",
"required": true
}
Expand Down
4 changes: 2 additions & 2 deletions docs/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -327,9 +327,9 @@ paths:
name: eon
required: true
type: integer
- description: Identity prefix associated with the event identity registration.
- description: Identity associated with the event identity registration.
in: query
name: identityPrefix
name: identity
required: true
type: string
produces:
Expand Down
28 changes: 28 additions & 0 deletions internal/middleware/event_api_guard.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package middleware

import (
"net/http"

"github.com/gin-gonic/gin"
"github.com/shutter-network/shutter-api/common"
sherror "github.com/shutter-network/shutter-api/internal/error"
)

// EventAPIGuard returns 501 Not Implemented when DisableEventAPI is true
// (i.e., when SHUTTER_EVENT_REGISTRY_CONTRACT_ADDRESS is not configured).
// When enabled, requests proceed to the event handlers.
func EventAPIGuard(config *common.Config) gin.HandlerFunc {
return func(ctx *gin.Context) {
if config.DisableEventAPI {
err := sherror.NewHttpError(
"Service is unavailable.",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should then align this error message with the 501 error, and have it as "Event API is disabled on this deployment" instead of "Service unavailable" which is usually with the 503 error code?

"Service is unavailable.",
http.StatusNotImplemented,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This new response is not reflected on the API docs, example here: https://github.com/shutter-network/shutter-api/blob/main/internal/service/crypto.go#L53 and in other endpoints.

)
ctx.Error(err)
ctx.Abort()
return
}
ctx.Next()
}
}
1 change: 1 addition & 0 deletions internal/router/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ func NewRouter(
}

eventGroup := api.Group("/event")
eventGroup.Use(middleware.EventAPIGuard(config))
{
eventGroup.POST("/compile_trigger_definition", cryptoService.CompileEventTriggerDefinition)
eventGroup.POST("/register_identity", cryptoService.RegisterEventIdentity)
Expand Down
5 changes: 5 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,11 @@ func main() {
log.Err(err).Msg("unable to parse keyper http url")
return
}
// Disable event API if event registry contract address is not configured
config.DisableEventAPI = shutterEventRegistryContractAddressStringified == ""
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps a more robust check would be to verify that the event registry is a valid Ethereum address and enable the corresponding services then?

if config.DisableEventAPI {
log.Info().Msg("Event API disabled: SHUTTER_EVENT_REGISTRY_CONTRACT_ADDRESS not configured")
}
app := router.NewRouter(ctx, db, contract, client, config)
watcher := watcher.NewWatcher(config, db)
group, deferFn := service.RunBackground(ctx, watcher)
Expand Down
1 change: 1 addition & 0 deletions tests/integration/init_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ func (s *TestShutterService) SetupSuite() {

s.config, err = common.NewConfig(keyperHTTPUrl, signingKey, &p2pConfig)
s.Require().NoError(err)
s.config.DisableEventAPI = false

rpc_url := os.Getenv("RPC_URL")
s.ethClient, err = ethclient.Dial(rpc_url)
Expand Down