Repository: libp2p/go-libp2p
Pull request #2640 (2023-11-12 22:36:49)

Fix Swarm Grafana Dashboard
When using the existing Grafana setup, the newer versions of Grafana fail to provision the Swarm dashboard. It works when importing it manually, but it fails during the automatic provisioning, complaining about not being able to transform legacy templates.

Apparently the issues is in the format of the `templating` field of the dashboard JSON. I adapted it from the other dashboards that seem to work just fine with provisioning.

sukunrt: Thanks @burdiyan Can you tell me the grafana version it is failing with? 

Patch:
diff --git a/.github/workflows/go-check.yml b/.github/workflows/go-check.yml
index c469d491..09ee2fc9 100644
--- a/.github/workflows/go-check.yml
+++ b/.github/workflows/go-check.yml
@@ -16,3 +16,5 @@ concurrency:
 jobs:
   go-check:
     uses: pl-strflt/uci/.github/workflows/go-check.yml@v0.0
+    with:
+      go-generate-ignore-protoc-version-comments: true
diff --git a/dashboards/docker-compose.base.yml b/dashboards/docker-compose.base.yml
index 4c87d284..b46514af 100644
--- a/dashboards/docker-compose.base.yml
+++ b/dashboards/docker-compose.base.yml
@@ -26,3 +26,4 @@ services:
       - ./identify/identify.json:/var/lib/grafana/dashboards/identify.json
       - ./relaysvc/relaysvc.json:/var/lib/grafana/dashboards/relaysvc.json
       - ./swarm/swarm.json:/var/lib/grafana/dashboards/swarm.json
+      - ./resource-manager/resource-manager.json:/var/lib/grafana/dashboards/resource-manager.json
diff --git a/dashboards/swarm/swarm.json b/dashboards/swarm/swarm.json
index e5f2fe7e..d206de29 100644
--- a/dashboards/swarm/swarm.json
+++ b/dashboards/swarm/swarm.json
@@ -232,9 +232,7 @@
       "options": {
         "orientation": "auto",
         "reduceOptions": {
-          "calcs": [
-            "lastNotNull"
-          ],
+          "calcs": ["lastNotNull"],
           "fields": "",
           "values": false
         },
@@ -1139,9 +1137,7 @@
         },
         "pieType": "pie",
         "reduceOptions": {
-          "calcs": [
-            "lastNotNull"
-          ],
+          "calcs": ["lastNotNull"],
           "fields": "",
           "values": false
         },
@@ -1816,9 +1812,7 @@
         },
         "pieType": "pie",
         "reduceOptions": {
-          "calcs": [
-            "lastNotNull"
-          ],
+          "calcs": ["lastNotNull"],
           "fields": "",
           "values": false
         },
@@ -2016,9 +2010,7 @@
         },
         "pieType": "pie",
         "reduceOptions": {
-          "calcs": [
-            "lastNotNull"
-          ],
+          "calcs": ["lastNotNull"],
           "fields": "",
           "values": false
         },
@@ -2110,9 +2102,7 @@
         },
         "pieType": "pie",
         "reduceOptions": {
-          "calcs": [
-            "lastNotNull"
-          ],
+          "calcs": ["lastNotNull"],
           "fields": "",
           "values": false
         },
@@ -2205,9 +2195,7 @@
         },
         "pieType": "pie",
         "reduceOptions": {
-          "calcs": [
-            "lastNotNull"
-          ],
+          "calcs": ["lastNotNull"],
           "fields": "",
           "values": false
         },
@@ -2372,15 +2360,11 @@
           "displayMode": "table",
           "placement": "right",
           "showLegend": true,
-          "values": [
-            "percent"
-          ]
+          "values": ["percent"]
         },
         "pieType": "donut",
         "reduceOptions": {
-          "calcs": [
-            "lastNotNull"
-          ],
+          "calcs": ["lastNotNull"],
           "fields": "",
           "values": false
         },
@@ -2652,9 +2636,7 @@
         },
         "pieType": "pie",
         "reduceOptions": {
-          "calcs": [
-            "lastNotNull"
-          ],
+          "calcs": ["lastNotNull"],
           "fields": "",
           "values": false
         },
@@ -2798,22 +2780,16 @@
       },
       "id": 38,
       "options": {
-        "displayLabels": [
-          "percent"
-        ],
+        "displayLabels": ["percent"],
         "legend": {
           "displayMode": "table",
           "placement": "right",
           "showLegend": true,
-          "values": [
-            "percent"
-          ]
+          "values": ["percent"]
         },
         "pieType": "donut",
         "reduceOptions": {
-          "calcs": [
-            "lastNotNull"
-          ],
+          "calcs": ["lastNotNull"],
           "fields": "",
           "values": false
         },
@@ -3036,23 +3012,16 @@
       },
       "id": 42,
       "options": {
-        "displayLabels": [
-          "percent",
-          "name"
-        ],
+        "displayLabels": ["percent", "name"],
         "legend": {
           "displayMode": "table",
           "placement": "right",
           "showLegend": true,
-          "values": [
-            "percent"
-          ]
+          "values": ["percent"]
         },
         "pieType": "donut",
         "reduceOptions": {
-          "calcs": [
-            "lastNotNull"
-          ],
+          "calcs": ["lastNotNull"],
           "fields": "",
           "values": false
         },
@@ -3296,9 +3265,7 @@
         "justifyMode": "auto",
         "orientation": "horizontal",
         "reduceOptions": {
-          "calcs": [
-            "lastNotNull"
-          ],
+          "calcs": ["lastNotNull"],
           "fields": "",
           "values": false
         },
@@ -3360,9 +3327,7 @@
       "options": {
         "orientation": "vertical",
         "reduceOptions": {
-          "calcs": [
-            "lastNotNull"
-          ],
+          "calcs": ["lastNotNull"],
           "fields": "",
           "values": false
         },
@@ -3395,6 +3360,16 @@
   "tags": [],
   "templating": {
     "list": [
+      {
+        "hide": 0,
+        "label": "datasource",
+        "name": "DS_PROMETHEUS",
+        "options": [],
+        "query": "prometheus",
+        "refresh": 1,
+        "regex": "",
+        "type": "datasource"
+      },
       {
         "current": {},
         "datasource": {
@@ -3412,7 +3387,6 @@
           "refId": "StandardVariableQuery"
         },
         "refresh": 1,
-        "regex": "",
         "skipUrlSync": false,
         "sort": 0,
         "type": "query"
@@ -3429,4 +3403,4 @@
   "uid": "a15PyhO4z",
   "version": 4,
   "weekStart": ""
-}
\ No newline at end of file
+}
diff --git a/examples/echo/README.md b/examples/echo/README.md
index 38071600..4c30609f 100644
--- a/examples/echo/README.md
+++ b/examples/echo/README.md
@@ -42,7 +42,7 @@ The `makeBasicHost()` function creates a [go-libp2p-basichost](https://godoc.org
 
 In order to create the swarm (and a `basichost`), the example needs:
 
-- An [ipfs-procotol ID](https://godoc.org/github.com/libp2p/go-libp2p-peer#ID) like `QmNtX1cvrm2K6mQmMEaMxAuB4rTexhd87vpYVot4sEZzxc`. The example autogenerates a key pair on every run and uses an ID extracted from the public key (the hash of the public key). When using `-insecure`, it leaves the connection unencrypted (otherwise, it uses the key pair to encrypt communications).
+- An [ipfs-protocol ID](https://godoc.org/github.com/libp2p/go-libp2p-peer#ID) like `QmNtX1cvrm2K6mQmMEaMxAuB4rTexhd87vpYVot4sEZzxc`. The example autogenerates a key pair on every run and uses an ID extracted from the public key (the hash of the public key). When using `-insecure`, it leaves the connection unencrypted (otherwise, it uses the key pair to encrypt communications).
 - A [Multiaddress](https://godoc.org/github.com/multiformats/go-multiaddr), which indicates how to reach this peer. There can be several of them (using different protocols or locations for example). Example: `/ip4/127.0.0.1/tcp/1234`.
 - A [go-libp2p-peerstore](https://godoc.org/github.com/libp2p/go-libp2p-peerstore), which is used as an address book which matches node IDs to the multiaddresses through which they can be contacted. This peerstore gets autopopulated when manually opening a connection (with [`Connect()`](https://godoc.org/github.com/libp2p/go-libp2p/p2p/host/basic#BasicHost.Connect). Alternatively, we can manually [`AddAddr()`](https://godoc.org/github.com/libp2p/go-libp2p-peerstore#AddrManager.AddAddr) as in the example.
 
diff --git a/examples/relay/main.go b/examples/relay/main.go
index e8fa8b7b..7e16b1b1 100644
--- a/examples/relay/main.go
+++ b/examples/relay/main.go
@@ -27,7 +27,7 @@ func run() {
 	unreachable1, err := libp2p.New(
 		libp2p.NoListenAddrs,
 		// Usually EnableRelay() is not required as it is enabled by default
-		// but NoListenAddrs overrides this, so we're adding it in explictly again.
+		// but NoListenAddrs overrides this, so we're adding it in explicitly again.
 		libp2p.EnableRelay(),
 	)
 	if err != nil {
diff --git a/p2p/host/basic/basic_host.go b/p2p/host/basic/basic_host.go
index 6c3ba53e..8e6e8efe 100644
--- a/p2p/host/basic/basic_host.go
+++ b/p2p/host/basic/basic_host.go
@@ -171,12 +171,11 @@ func NewHost(n network.Network, opts *HostOpts) (*BasicHost, error) {
 		opts.EventBus = eventbus.NewBus()
 	}
 
-	psManager, err := pstoremanager.NewPeerstoreManager(n.Peerstore(), opts.EventBus)
+	psManager, err := pstoremanager.NewPeerstoreManager(n.Peerstore(), opts.EventBus, n)
 	if err != nil {
 		return nil, err
 	}
 	hostCtx, cancel := context.WithCancel(context.Background())
-
 	h := &BasicHost{
 		network:                 n,
 		psManager:               psManager,
@@ -543,7 +542,7 @@ func (h *BasicHost) background() {
 			h.updateLocalIpAddr()
 		}
 		// Request addresses anyways because, technically, address filters still apply.
-		// The underlying AllAddrs call is effectivley a no-op.
+		// The underlying AllAddrs call is effectively a no-op.
 		curr := h.Addrs()
 		emitAddrChange(curr, lastAddrs)
 		lastAddrs = curr
diff --git a/p2p/host/pstoremanager/pstoremanager.go b/p2p/host/pstoremanager/pstoremanager.go
index d9550f49..2a22b2ca 100644
--- a/p2p/host/pstoremanager/pstoremanager.go
+++ b/p2p/host/pstoremanager/pstoremanager.go
@@ -41,6 +41,7 @@ func WithCleanupInterval(t time.Duration) Option {
 type PeerstoreManager struct {
 	pstore   peerstore.Peerstore
 	eventBus event.Bus
+	network  network.Network
 
 	cancel   context.CancelFunc
 	refCount sync.WaitGroup
@@ -49,11 +50,12 @@ type PeerstoreManager struct {
 	cleanupInterval time.Duration
 }
 
-func NewPeerstoreManager(pstore peerstore.Peerstore, eventBus event.Bus, opts ...Option) (*PeerstoreManager, error) {
+func NewPeerstoreManager(pstore peerstore.Peerstore, eventBus event.Bus, network network.Network, opts ...Option) (*PeerstoreManager, error) {
 	m := &PeerstoreManager{
 		pstore:      pstore,
 		gracePeriod: time.Minute,
 		eventBus:    eventBus,
+		network:     network,
 	}
 	for _, opt := range opts {
 		if err := opt(m); err != nil {
@@ -107,14 +109,21 @@ func (m *PeerstoreManager) background(ctx context.Context, sub event.Subscriptio
 				}
 			case network.Connected:
 				// If we reconnect to the peer before we've cleared the information, keep it.
+				// This is an optimization to keep the disconnected map small.
+				// We still need to check that a peer is actually disconnected before removing it from the peer store.
 				delete(disconnected, p)
 			}
 		case <-ticker.C:
 			now := time.Now()
 			for p, disconnectTime := range disconnected {
 				if disconnectTime.Add(m.gracePeriod).Before(now) {
-					m.pstore.RemovePeer(p)
-					delete(disconnected, p)
+					// Check that the peer is actually not connected at this point.
+					// This avoids a race condition where the Connected notification
+					// is processed after this time has fired.
+					if m.network.Connectedness(p) != network.Connected {
+						m.pstore.RemovePeer(p)
+						delete(disconnected, p)
+					}
 				}
 			}
 		case <-ctx.Done():


Test patch:
diff --git a/p2p/host/autonat/svc_test.go b/p2p/host/autonat/svc_test.go
index 61e6038c..96836d1d 100644
--- a/p2p/host/autonat/svc_test.go
+++ b/p2p/host/autonat/svc_test.go
@@ -189,7 +189,7 @@ func TestAutoNATServiceRateLimitJitter(t *testing.T) {
 		svc.mx.Lock()
 		defer svc.mx.Unlock()
 		return svc.globalReqs == 0
-	}, dur*5/2, 10*time.Millisecond, "reset of rate limitter occured slower than expected")
+	}, dur*5/2, 10*time.Millisecond, "reset of rate limitter occurred slower than expected")
 }
 
 func TestAutoNATServiceStartup(t *testing.T) {
diff --git a/p2p/host/pstoremanager/pstoremanager_test.go b/p2p/host/pstoremanager/pstoremanager_test.go
index bcfd8749..9321031c 100644
--- a/p2p/host/pstoremanager/pstoremanager_test.go
+++ b/p2p/host/pstoremanager/pstoremanager_test.go
@@ -9,6 +9,7 @@ import (
 	"github.com/libp2p/go-libp2p/core/peer"
 	"github.com/libp2p/go-libp2p/p2p/host/eventbus"
 	"github.com/libp2p/go-libp2p/p2p/host/pstoremanager"
+	swarmt "github.com/libp2p/go-libp2p/p2p/net/swarm/testing"
 
 	"github.com/stretchr/testify/require"
 	"go.uber.org/mock/gomock"
@@ -23,7 +24,7 @@ func TestGracePeriod(t *testing.T) {
 	eventBus := eventbus.NewBus()
 	pstore := NewMockPeerstore(ctrl)
 	const gracePeriod = 250 * time.Millisecond
-	man, err := pstoremanager.NewPeerstoreManager(pstore, eventBus, pstoremanager.WithGracePeriod(gracePeriod))
+	man, err := pstoremanager.NewPeerstoreManager(pstore, eventBus, swarmt.GenSwarm(t), pstoremanager.WithGracePeriod(gracePeriod))
 	require.NoError(t, err)
 	defer man.Close()
 	man.Start()
@@ -51,7 +52,7 @@ func TestReconnect(t *testing.T) {
 	eventBus := eventbus.NewBus()
 	pstore := NewMockPeerstore(ctrl)
 	const gracePeriod = 200 * time.Millisecond
-	man, err := pstoremanager.NewPeerstoreManager(pstore, eventBus, pstoremanager.WithGracePeriod(gracePeriod))
+	man, err := pstoremanager.NewPeerstoreManager(pstore, eventBus, swarmt.GenSwarm(t), pstoremanager.WithGracePeriod(gracePeriod))
 	require.NoError(t, err)
 	defer man.Close()
 	man.Start()
@@ -77,7 +78,7 @@ func TestClose(t *testing.T) {
 	eventBus := eventbus.NewBus()
 	pstore := NewMockPeerstore(ctrl)
 	const gracePeriod = time.Hour
-	man, err := pstoremanager.NewPeerstoreManager(pstore, eventBus, pstoremanager.WithGracePeriod(gracePeriod))
+	man, err := pstoremanager.NewPeerstoreManager(pstore, eventBus, swarmt.GenSwarm(t), pstoremanager.WithGracePeriod(gracePeriod))
 	require.NoError(t, err)
 	man.Start()
 
diff --git a/p2p/net/swarm/dial_test.go b/p2p/net/swarm/dial_test.go
index a614183b..3b139ef3 100644
--- a/p2p/net/swarm/dial_test.go
+++ b/p2p/net/swarm/dial_test.go
@@ -562,7 +562,7 @@ func TestDialSimultaneousJoin(t *testing.T) {
 			return
 		}
 
-		t.Logf("first dial succedded; conn: %+v", c)
+		t.Logf("first dial succeeded; conn: %+v", c)
 
 		connch <- c
 		errs <- nil
@@ -587,7 +587,7 @@ func TestDialSimultaneousJoin(t *testing.T) {
 			return
 		}
 
-		t.Logf("second dial succedded; conn: %+v", c)
+		t.Logf("second dial succeeded; conn: %+v", c)
 
 		connch <- c
 		errs <- nil
@@ -605,7 +605,7 @@ func TestDialSimultaneousJoin(t *testing.T) {
 			return
 		}
 
-		t.Logf("third dial succedded; conn: %+v", c)
+		t.Logf("third dial succeeded; conn: %+v", c)
 
 		connch <- c
 		errs <- nil