Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/rc/v1.7.0' into SF-v1.7.0
Browse files Browse the repository at this point in the history
  • Loading branch information
raduchis committed Jan 30, 2024
2 parents 67ad2eb + e2a3c3d commit 72201bf
Show file tree
Hide file tree
Showing 359 changed files with 9,099 additions and 10,456 deletions.
30 changes: 30 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,36 @@ sudo cp protoc-gen-gogoslick /usr/bin/

Done

## Running p2p Prometheus dashboards
1. Start the node with `--p2p-prometheus-metrics` flag. This exposes a metrics collection at http://localhost:8080/debug/metrics/prometheus (port defined by -rest-api-interface flag, default 8080)
2. Clone libp2p repository: `git clone https://github.com/libp2p/go-libp2p`
3. `cd go-libp2p/dasboards/swarm` and under the
```
"templating": {
"list": [
```
section, add the following lines:
```
{
"hide": 0,
"label": "datasource",
"name": "DS_PROMETHEUS",
"options": [],
"query": "prometheus",
"refresh": 1,
"regex": "",
"type": "datasource"
},
```
(this step will be removed once it will be fixed on libp2p)
4. `cd ..` to dashboards directory and update the port of `host.docker.internal` from `prometheus.yml` to node's Rest API port(default `8080`)
5. From this directory, run the following docker compose command:
```
sudo docker compose -f docker-compose.base.yml -f docker-compose-linux.yml up --force-recreate
```
**Note:** If you choose to install the new Docker version manually, please make sure that installation is done for all users of the system. Otherwise, the docker command will fail because it needs the super-user privileges.
6. The preconfigured dashboards should be now available on Grafana at http://localhost:3000/dashboards

## Progress

### Done
Expand Down
3 changes: 3 additions & 0 deletions api/errors/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,3 +171,6 @@ var ErrGetEligibleManagedKeys = errors.New("error getting the eligible managed k

// ErrGetWaitingManagedKeys signals that an error occurred while getting the waiting managed keys
var ErrGetWaitingManagedKeys = errors.New("error getting the waiting managed keys")

// ErrGetWaitingEpochsLeftForPublicKey signals that an error occurred while getting the waiting epochs left for public key
var ErrGetWaitingEpochsLeftForPublicKey = errors.New("error getting the waiting epochs left for public key")
7 changes: 6 additions & 1 deletion api/gin/common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,12 @@ func TestCommon_checkArgs(t *testing.T) {
err := checkArgs(args)
require.True(t, errors.Is(err, apiErrors.ErrCannotCreateGinWebServer))

args.Facade, err = initial.NewInitialNodeFacade("api interface", false, &testscommon.StatusMetricsStub{})
args.Facade, err = initial.NewInitialNodeFacade(initial.ArgInitialNodeFacade{
ApiInterface: "api interface",
PprofEnabled: false,
P2PPrometheusMetricsEnabled: false,
StatusMetricsHandler: &testscommon.StatusMetricsStub{},
})
require.NoError(t, err)
err = checkArgs(args)
require.NoError(t, err)
Expand Down
7 changes: 7 additions & 0 deletions api/gin/webServer.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,13 @@ import (
"github.com/multiversx/mx-chain-go/config"
"github.com/multiversx/mx-chain-go/facade"
logger "github.com/multiversx/mx-chain-logger-go"
"github.com/prometheus/client_golang/prometheus/promhttp"
)

var log = logger.GetOrCreate("api/gin")

const prometheusMetricsRoute = "/debug/metrics/prometheus"

// ArgsNewWebServer holds the arguments needed to create a new instance of webServer
type ArgsNewWebServer struct {
Facade shared.FacadeHandler
Expand Down Expand Up @@ -227,6 +230,10 @@ func (ws *webServer) registerRoutes(ginRouter *gin.Engine) {
if ws.facade.PprofEnabled() {
pprof.Register(ginRouter)
}

if ws.facade.P2PPrometheusMetricsEnabled() {
ginRouter.GET(prometheusMetricsRoute, gin.WrapH(promhttp.Handler()))
}
}

func (ws *webServer) createMiddlewareLimiters() ([]shared.MiddlewareProcessor, error) {
Expand Down
19 changes: 19 additions & 0 deletions api/groups/nodeGroup.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ const (
managedKeysCount = "/managed-keys/count"
eligibleManagedKeys = "/managed-keys/eligible"
waitingManagedKeys = "/managed-keys/waiting"
epochsLeftInWaiting = "/waiting-epochs-left/:key"
)

// nodeFacadeHandler defines the methods to be implemented by a facade for node requests
Expand All @@ -45,6 +46,7 @@ type nodeFacadeHandler interface {
GetManagedKeys() []string
GetEligibleManagedKeys() ([]string, error)
GetWaitingManagedKeys() ([]string, error)
GetWaitingEpochsLeftForPublicKey(publicKey string) (uint32, error)
IsInterfaceNil() bool
}

Expand Down Expand Up @@ -137,6 +139,11 @@ func NewNodeGroup(facade nodeFacadeHandler) (*nodeGroup, error) {
Method: http.MethodGet,
Handler: ng.managedKeysWaiting,
},
{
Path: epochsLeftInWaiting,
Method: http.MethodGet,
Handler: ng.waitingEpochsLeft,
},
}
ng.endpoints = endpoints

Expand Down Expand Up @@ -440,6 +447,18 @@ func (ng *nodeGroup) managedKeysWaiting(c *gin.Context) {
)
}

// waitingEpochsLeft returns the number of epochs left for the public key until it becomes eligible
func (ng *nodeGroup) waitingEpochsLeft(c *gin.Context) {
publicKey := c.Param("key")
epochsLeft, err := ng.getFacade().GetWaitingEpochsLeftForPublicKey(publicKey)
if err != nil {
shared.RespondWithInternalError(c, errors.ErrGetWaitingEpochsLeftForPublicKey, err)
return
}

shared.RespondWithSuccess(c, gin.H{"epochsLeft": epochsLeft})
}

func (ng *nodeGroup) getFacade() nodeFacadeHandler {
ng.mutFacade.RLock()
defer ng.mutFacade.RUnlock()
Expand Down
87 changes: 87 additions & 0 deletions api/groups/nodeGroup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,13 @@ type managedWaitingKeysResponse struct {
generalResponse
}

type waitingEpochsLeftResponse struct {
Data struct {
EpochsLeft uint32 `json:"epochsLeft"`
} `json:"data"`
generalResponse
}

func init() {
gin.SetMode(gin.TestMode)
}
Expand Down Expand Up @@ -276,6 +283,30 @@ func TestBootstrapStatusMetrics_ShouldWork(t *testing.T) {
func TestNodeGroup_GetConnectedPeersRatings(t *testing.T) {
t.Parallel()

t.Run("facade error should error", func(t *testing.T) {
t.Parallel()

facade := mock.FacadeStub{
GetConnectedPeersRatingsOnMainNetworkCalled: func() (string, error) {
return "", expectedErr
},
}

nodeGroup, err := groups.NewNodeGroup(&facade)
require.NoError(t, err)

ws := startWebServer(nodeGroup, "node", getNodeRoutesConfig())

req, _ := http.NewRequest("GET", "/node/connected-peers-ratings", nil)
resp := httptest.NewRecorder()
ws.ServeHTTP(resp, req)

response := &shared.GenericAPIResponse{}
loadResponse(resp.Body, response)

assert.Equal(t, http.StatusInternalServerError, resp.Code)
assert.True(t, strings.Contains(response.Error, expectedErr.Error()))
})
t.Run("should work", func(t *testing.T) {
t.Parallel()

Expand Down Expand Up @@ -851,6 +882,61 @@ func TestNodeGroup_ManagedKeysWaiting(t *testing.T) {
})
}

func TestNodeGroup_WaitingEpochsLeft(t *testing.T) {
t.Parallel()

t.Run("facade error should error", func(t *testing.T) {
t.Parallel()

facade := mock.FacadeStub{
GetWaitingEpochsLeftForPublicKeyCalled: func(publicKey string) (uint32, error) {
return 0, expectedErr
},
}

nodeGroup, err := groups.NewNodeGroup(&facade)
require.NoError(t, err)

ws := startWebServer(nodeGroup, "node", getNodeRoutesConfig())

req, _ := http.NewRequest("GET", "/node/waiting-epochs-left/key", nil)
resp := httptest.NewRecorder()
ws.ServeHTTP(resp, req)

response := &shared.GenericAPIResponse{}
loadResponse(resp.Body, response)

assert.Equal(t, http.StatusInternalServerError, resp.Code)
assert.True(t, strings.Contains(response.Error, expectedErr.Error()))
})
t.Run("should work", func(t *testing.T) {
t.Parallel()

providedEpochsLeft := uint32(10)
facade := mock.FacadeStub{
GetWaitingEpochsLeftForPublicKeyCalled: func(publicKey string) (uint32, error) {
return providedEpochsLeft, nil
},
}

nodeGroup, err := groups.NewNodeGroup(&facade)
require.NoError(t, err)

ws := startWebServer(nodeGroup, "node", getNodeRoutesConfig())

req, _ := http.NewRequest("GET", "/node/waiting-epochs-left/key", nil)
resp := httptest.NewRecorder()
ws.ServeHTTP(resp, req)

response := &waitingEpochsLeftResponse{}
loadResponse(resp.Body, response)

assert.Equal(t, http.StatusOK, resp.Code)
assert.Equal(t, "", response.Error)
assert.Equal(t, providedEpochsLeft, response.Data.EpochsLeft)
})
}

func TestNodeGroup_UpdateFacade(t *testing.T) {
t.Parallel()

Expand Down Expand Up @@ -962,6 +1048,7 @@ func getNodeRoutesConfig() config.ApiRoutesConfig {
{Name: "/managed-keys", Open: true},
{Name: "/managed-keys/eligible", Open: true},
{Name: "/managed-keys/waiting", Open: true},
{Name: "/waiting-epochs-left/:key", Open: true},
},
},
},
Expand Down
Loading

0 comments on commit 72201bf

Please sign in to comment.