Skip to content

Commit

Permalink
Implement relays checker
Browse files Browse the repository at this point in the history
  • Loading branch information
pablomendezroyo committed Dec 3, 2024
1 parent f70b9b7 commit 1800ddc
Show file tree
Hide file tree
Showing 11 changed files with 1,918 additions and 14 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" }
]
7 changes: 7 additions & 0 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ import (
csfeedistributor "lido-events/internal/adapters/csFeeDistributor"
csfeedistributorimpl "lido-events/internal/adapters/csFeeDistributorImpl"
csmodule "lido-events/internal/adapters/csModule"
"lido-events/internal/adapters/dappmanager"
"lido-events/internal/adapters/execution"
exitvalidator "lido-events/internal/adapters/exitValidator"
"lido-events/internal/adapters/ipfs"
relayschecker "lido-events/internal/adapters/mevBoostRelaysAllowList"
"lido-events/internal/adapters/notifier"
proxyapi "lido-events/internal/adapters/proxyApi"
"lido-events/internal/adapters/storage"
Expand Down Expand Up @@ -67,6 +69,11 @@ func main() {
if err != nil {
logger.Warn("Telegram notifier not initialized: %v", err)
}
dappmanagerAdapter := dappmanager.NewDappmanagerAdapter(networkConfig.DappmanagerUrl, networkConfig.MevBoostDnpName)
relaysAllowListAdapter, err := relayschecker.NewRelaysCheckerAdapter(networkConfig.WsURL, networkConfig.MEVBoostRelaysAllowListAddres, networkConfig.DappmanagerUrl, networkConfig.MevBoostDnpName)
if err != nil {
logger.Fatal("Failed to initialize RelaysChecker adapter: %v", err)
}

// Start HTTP server
apiAdapter := api.NewAPIAdapter(storageAdapter, notifierAdapter, networkConfig.CORS)
Expand Down
45 changes: 36 additions & 9 deletions internal/adapters/api/api_adapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,23 @@ import (

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

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

// Set up API routes
Expand Down Expand Up @@ -57,13 +61,36 @@ 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()
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)
}

// GetTelegramConfig retrieves the Telegram configuration
func (h *APIHandler) GetTelegramConfig(w http.ResponseWriter, r *http.Request) {
logger.DebugWithPrefix("API", "GetTelegramConfig request received")
Expand Down
45 changes: 45 additions & 0 deletions internal/adapters/dappmanager/dappmanager_adapter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package dappmanager

import (
"context"
"encoding/json"
"fmt"
"net/http"
)

type DappmanagerAdapter struct {
dappmanagerUrl string
mevBootDnpName string
}

// NewDappmanagerAdapter creates a new instance of DappmanagerAdapter with provided dappmanagerUrl and mevBoostDnpName
func NewDappmanagerAdapter(dappmanagerUrl, mevBoostDnpName string) *DappmanagerAdapter {
return &DappmanagerAdapter{
dappmanagerUrl,
mevBoostDnpName,
}
}

// GetRelaysUsed fetches env RELAYS from MEV BOOST pkg
func (da *DappmanagerAdapter) GetRelaysUsed(ctx context.Context) ([]string, error) {
url := fmt.Sprintf("%s/env/%s?envName=RELAYS", da.dappmanagerUrl, da.mevBootDnpName)
req, err := http.NewRequest("GET", url, nil)
if err != nil {
return nil, fmt.Errorf("failed to create GET request for URL %s: %w", url, err)
}

client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, fmt.Errorf("failed to send request to Dappmanager at %s: %w", url, err)
}

defer resp.Body.Close()

var result []string
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
return nil, fmt.Errorf("failed to decode response for GetRelaysUsed: %w", err)
}

return result, nil
}
Loading

0 comments on commit 1800ddc

Please sign in to comment.