Skip to content

Commit

Permalink
Implement relays checker (#53)
Browse files Browse the repository at this point in the history
* Implement relays checker

* Implement api

* remove first execution complete

* run go

* fix get relays

* fix initialization

* remove new line
  • Loading branch information
pablomendezroyo authored Dec 5, 2024
1 parent 3c48f85 commit 00ac8e0
Show file tree
Hide file tree
Showing 11 changed files with 1,963 additions and 13 deletions.
182 changes: 182 additions & 0 deletions abi/MEVBoostRelaysAllowList.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
[
{
"name": "RelayAdded",
"inputs": [
{ "name": "uri_hash", "type": "string", "indexed": true },
{
"name": "relay",
"type": "tuple",
"components": [
{ "name": "uri", "type": "string" },
{ "name": "operator", "type": "string" },
{ "name": "is_mandatory", "type": "bool" },
{ "name": "description", "type": "string" }
],
"indexed": false
}
],
"anonymous": false,
"type": "event"
},
{
"name": "RelayRemoved",
"inputs": [
{ "name": "uri_hash", "type": "string", "indexed": true },
{ "name": "uri", "type": "string", "indexed": false }
],
"anonymous": false,
"type": "event"
},
{
"name": "AllowedListUpdated",
"inputs": [
{ "name": "allowed_list_version", "type": "uint256", "indexed": true }
],
"anonymous": false,
"type": "event"
},
{
"name": "OwnerChanged",
"inputs": [{ "name": "new_owner", "type": "address", "indexed": true }],
"anonymous": false,
"type": "event"
},
{
"name": "ManagerChanged",
"inputs": [{ "name": "new_manager", "type": "address", "indexed": true }],
"anonymous": false,
"type": "event"
},
{
"name": "ERC20Recovered",
"inputs": [
{ "name": "token", "type": "address", "indexed": true },
{ "name": "amount", "type": "uint256", "indexed": false },
{ "name": "recipient", "type": "address", "indexed": true }
],
"anonymous": false,
"type": "event"
},
{
"stateMutability": "nonpayable",
"type": "constructor",
"inputs": [{ "name": "owner", "type": "address" }],
"outputs": []
},
{
"stateMutability": "view",
"type": "function",
"name": "get_relays_amount",
"inputs": [],
"outputs": [{ "name": "", "type": "uint256" }]
},
{
"stateMutability": "view",
"type": "function",
"name": "get_owner",
"inputs": [],
"outputs": [{ "name": "", "type": "address" }]
},
{
"stateMutability": "view",
"type": "function",
"name": "get_manager",
"inputs": [],
"outputs": [{ "name": "", "type": "address" }]
},
{
"stateMutability": "view",
"type": "function",
"name": "get_relays",
"inputs": [],
"outputs": [
{
"name": "",
"type": "tuple[]",
"components": [
{ "name": "uri", "type": "string" },
{ "name": "operator", "type": "string" },
{ "name": "is_mandatory", "type": "bool" },
{ "name": "description", "type": "string" }
]
}
]
},
{
"stateMutability": "view",
"type": "function",
"name": "get_relay_by_uri",
"inputs": [{ "name": "relay_uri", "type": "string" }],
"outputs": [
{
"name": "",
"type": "tuple",
"components": [
{ "name": "uri", "type": "string" },
{ "name": "operator", "type": "string" },
{ "name": "is_mandatory", "type": "bool" },
{ "name": "description", "type": "string" }
]
}
]
},
{
"stateMutability": "view",
"type": "function",
"name": "get_allowed_list_version",
"inputs": [],
"outputs": [{ "name": "", "type": "uint256" }]
},
{
"stateMutability": "nonpayable",
"type": "function",
"name": "add_relay",
"inputs": [
{ "name": "uri", "type": "string" },
{ "name": "operator", "type": "string" },
{ "name": "is_mandatory", "type": "bool" },
{ "name": "description", "type": "string" }
],
"outputs": []
},
{
"stateMutability": "nonpayable",
"type": "function",
"name": "remove_relay",
"inputs": [{ "name": "uri", "type": "string" }],
"outputs": []
},
{
"stateMutability": "nonpayable",
"type": "function",
"name": "change_owner",
"inputs": [{ "name": "owner", "type": "address" }],
"outputs": []
},
{
"stateMutability": "nonpayable",
"type": "function",
"name": "set_manager",
"inputs": [{ "name": "manager", "type": "address" }],
"outputs": []
},
{
"stateMutability": "nonpayable",
"type": "function",
"name": "dismiss_manager",
"inputs": [],
"outputs": []
},
{
"stateMutability": "nonpayable",
"type": "function",
"name": "recover_erc20",
"inputs": [
{ "name": "token", "type": "address" },
{ "name": "amount", "type": "uint256" },
{ "name": "recipient", "type": "address" }
],
"outputs": []
},
{ "stateMutability": "nonpayable", "type": "fallback" }
]
12 changes: 11 additions & 1 deletion cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import (
"lido-events/internal/adapters/ipfs"
"lido-events/internal/adapters/notifier"
proxyapi "lido-events/internal/adapters/proxyApi"
relaysallowed "lido-events/internal/adapters/relaysAllowed"
relaysused "lido-events/internal/adapters/relaysUsed"
"lido-events/internal/adapters/storage"
"lido-events/internal/adapters/vebo"
"lido-events/internal/application/services"
Expand Down Expand Up @@ -46,8 +48,13 @@ func main() {
if err != nil {
logger.WarnWithPrefix(logPrefix, "Telegram notifier not initialized: %v", err)
}
relaysUsedAdapter := relaysused.NewRelaysUsedAdapter(networkConfig.DappmanagerUrl, networkConfig.MevBoostDnpName)
relaysAllowedAdapter, err := relaysallowed.NewRelaysAllowedAdapter(networkConfig.WsURL, networkConfig.MEVBoostRelaysAllowListAddres, networkConfig.DappmanagerUrl, networkConfig.MevBoostDnpName)
if err != nil {
logger.Fatal("Failed to initialize relaysAllowedAdapter: %v", err)
}

apiAdapter := api.NewAPIAdapter(storageAdapter, networkConfig.CORS)
apiAdapter := api.NewAPIAdapter(ctx, storageAdapter, relaysUsedAdapter, relaysAllowedAdapter, networkConfig.CORS)
proxyApiAdapter := proxyapi.NewProxyAPIAdapter(networkConfig.CORS, networkConfig.LidoKeysApiUrl)

// Initialize API services
Expand Down Expand Up @@ -91,8 +98,11 @@ func main() {
validatorExitRequestScannerService := services.NewValidatorExitRequestEventScanner(storageAdapter, notifierAdapter, veboAdapter, executionAdapter, beaconchainAdapter, networkConfig.VeboBlockDeployment)
validatorEjectorService := services.NewValidatorEjectorService(storageAdapter, notifierAdapter, exitValidatorAdapter, beaconchainAdapter)
pendingHashesLoaderService := services.NewPendingHashesLoader(storageAdapter, ipfsAdapter)
relaysCheckerService := services.NewRelayCronService(relaysAllowedAdapter, relaysUsedAdapter, notifierAdapter)

// Start domain services
go relaysCheckerService.StartRelayMonitoringCron(ctx, 5*time.Minute, &wg)

distributionLogUpdatedExecutionComplete := make(chan struct{})
go distributionLogUpdatedScannerService.ScanDistributionLogUpdatedEventsCron(ctx, 384*time.Second, &wg, distributionLogUpdatedExecutionComplete)
go pendingHashesLoaderService.LoadPendingHashesCron(ctx, 3*time.Hour, &wg, distributionLogUpdatedExecutionComplete)
Expand Down
66 changes: 59 additions & 7 deletions internal/adapters/api/api_adapter.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package api

import (
"context"
"encoding/json"
"math/big"
"net/http"
Expand All @@ -15,9 +16,13 @@ import (

// APIHandler holds the necessary dependencies for API endpoints
type APIHandler struct {
StoragePort ports.StoragePort
Router *mux.Router
adapterPrefix string
ctx context.Context
StoragePort ports.StoragePort
NotifierPort ports.NotifierPort
RelaysUsedPort ports.RelaysUsedPort
RelaysAllowedPort ports.RelaysAllowedPort
Router *mux.Router
adapterPrefix string
}

// Ensure APIHandler implements the ports.API interface
Expand All @@ -29,11 +34,14 @@ func (h *APIHandler) GetRouter() http.Handler {
}

// NewAPIAdapter initializes the APIHandler and sets up routes with CORS enabled
func NewAPIAdapter(storagePort ports.StoragePort, allowedOrigins []string) *APIHandler {
func NewAPIAdapter(ctx context.Context, storagePort ports.StoragePort, relaysUsedPort ports.RelaysUsedPort, relaysAllowedPort ports.RelaysAllowedPort, allowedOrigins []string) *APIHandler {
h := &APIHandler{
StoragePort: storagePort,
Router: mux.NewRouter(),
adapterPrefix: "API",
ctx: ctx,
StoragePort: storagePort,
RelaysUsedPort: relaysUsedPort,
RelaysAllowedPort: relaysAllowedPort,
Router: mux.NewRouter(),
adapterPrefix: "API",
}

// Set up API routes
Expand Down Expand Up @@ -63,13 +71,57 @@ func (h *APIHandler) SetupRoutes() {
h.Router.HandleFunc("/api/v0/events_indexer/operatorId", h.DeleteOperator).Methods("DELETE", "OPTIONS")
h.Router.HandleFunc("/api/v0/events_indexer/operator_performance", h.GetOperatorPerformance).Methods("GET", "OPTIONS")
h.Router.HandleFunc("/api/v0/events_indexer/exit_requests", h.GetExitRequests).Methods("GET", "OPTIONS")
h.Router.HandleFunc("/api/v0/events_indexer/relays_allowed", h.GetRelaysAllowed).Methods("GET", "OPTIONS")
h.Router.HandleFunc("/api/v0/events_indexer/relays_used", h.GetRelaysUsed).Methods("GET", "OPTIONS")

// Add a generic OPTIONS handler to ensure preflight requests are handled
h.Router.Methods("OPTIONS").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK) // Respond to OPTIONS requests with 200 OK
})
}

// GetRelaysAllowed retrieves the list of allowed relays
func (h *APIHandler) GetRelaysAllowed(w http.ResponseWriter, r *http.Request) {
logger.DebugWithPrefix("API", "GetRelaysAllowed request received")
relays, err := h.RelaysAllowedPort.GetRelaysAllowList(h.ctx)
if err != nil {
logger.ErrorWithPrefix("API", "Error fetching allowed relays: %v", err)
writeErrorResponse(w, "Error fetching allowed relays", http.StatusInternalServerError)
return
}

jsonResponse, err := json.Marshal(relays)
if err != nil {
logger.ErrorWithPrefix("API", "Error generating JSON response in GetRelaysAllowed: %v", err)
writeErrorResponse(w, "Error generating JSON response", http.StatusInternalServerError)
return
}

w.Header().Set("Content-Type", "application/json")
w.Write(jsonResponse)
}

// GetRelaysUsed retrieves the list of used relays
func (h *APIHandler) GetRelaysUsed(w http.ResponseWriter, r *http.Request) {
logger.DebugWithPrefix("API", "GetRelaysUsed request received")
relays, err := h.RelaysUsedPort.GetRelaysUsed(h.ctx)
if err != nil {
logger.ErrorWithPrefix("API", "Error fetching used relays: %v", err)
writeErrorResponse(w, "Error fetching used relays", http.StatusInternalServerError)
return
}

jsonResponse, err := json.Marshal(relays)
if err != nil {
logger.ErrorWithPrefix("API", "Error generating JSON response in GetRelaysUsed: %v", err)
writeErrorResponse(w, "Error generating JSON response", http.StatusInternalServerError)
return
}

w.Header().Set("Content-Type", "application/json")
w.Write(jsonResponse)
}

// GetTelegramConfig retrieves the Telegram configuration
func (h *APIHandler) GetTelegramConfig(w http.ResponseWriter, r *http.Request) {
logger.DebugWithPrefix("API", "GetTelegramConfig request received")
Expand Down
Loading

0 comments on commit 00ac8e0

Please sign in to comment.