From 93854bbad4fb819375463d04cf6b7e66b7f272f7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jano=C5=A1=20Gulja=C5=A1?= <janos@users.noreply.github.com>
Date: Mon, 26 Nov 2018 12:39:38 +0100
Subject: [PATCH] swarm/network/simulation: fix New function for-loop scope
 (#18161)

---
 swarm/network/simulation/node_test.go       | 35 +++++++++++++++++++++
 swarm/network/simulation/simulation.go      |  7 +++++
 swarm/network/simulation/simulation_test.go | 13 ++++++++
 swarm/network/stream/delivery.go            |  2 +-
 4 files changed, 56 insertions(+), 1 deletion(-)

diff --git a/swarm/network/simulation/node_test.go b/swarm/network/simulation/node_test.go
index 086ab606f..01346ef14 100644
--- a/swarm/network/simulation/node_test.go
+++ b/swarm/network/simulation/node_test.go
@@ -160,6 +160,41 @@ func TestAddNodeWithService(t *testing.T) {
 	}
 }
 
+func TestAddNodeMultipleServices(t *testing.T) {
+	sim := New(map[string]ServiceFunc{
+		"noop1": noopServiceFunc,
+		"noop2": noopService2Func,
+	})
+	defer sim.Close()
+
+	id, err := sim.AddNode()
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	n := sim.Net.GetNode(id).Node.(*adapters.SimNode)
+	if n.Service("noop1") == nil {
+		t.Error("service noop1 not found on node")
+	}
+	if n.Service("noop2") == nil {
+		t.Error("service noop2 not found on node")
+	}
+}
+
+func TestAddNodeDuplicateServiceError(t *testing.T) {
+	sim := New(map[string]ServiceFunc{
+		"noop1": noopServiceFunc,
+		"noop2": noopServiceFunc,
+	})
+	defer sim.Close()
+
+	wantErr := "duplicate service: *simulation.noopService"
+	_, err := sim.AddNode()
+	if err.Error() != wantErr {
+		t.Errorf("got error %q, want %q", err, wantErr)
+	}
+}
+
 func TestAddNodes(t *testing.T) {
 	sim := New(noopServiceFuncMap)
 	defer sim.Close()
diff --git a/swarm/network/simulation/simulation.go b/swarm/network/simulation/simulation.go
index f6d3ce229..e5435b9f0 100644
--- a/swarm/network/simulation/simulation.go
+++ b/swarm/network/simulation/simulation.go
@@ -68,6 +68,10 @@ type ServiceFunc func(ctx *adapters.ServiceContext, bucket *sync.Map) (s node.Se
 
 // New creates a new Simulation instance with new
 // simulations.Network initialized with provided services.
+// Services map must have unique keys as service names and
+// every ServiceFunc must return a node.Service of the unique type.
+// This restriction is required by node.Node.Start() function
+// which is used to start node.Service returned by ServiceFunc.
 func New(services map[string]ServiceFunc) (s *Simulation) {
 	s = &Simulation{
 		buckets: make(map[enode.ID]*sync.Map),
@@ -76,6 +80,9 @@ func New(services map[string]ServiceFunc) (s *Simulation) {
 
 	adapterServices := make(map[string]adapters.ServiceFunc, len(services))
 	for name, serviceFunc := range services {
+		// Scope this variables correctly
+		// as they will be in the adapterServices[name] function accessed later.
+		name, serviceFunc := name, serviceFunc
 		s.serviceNames = append(s.serviceNames, name)
 		adapterServices[name] = func(ctx *adapters.ServiceContext) (node.Service, error) {
 			b := new(sync.Map)
diff --git a/swarm/network/simulation/simulation_test.go b/swarm/network/simulation/simulation_test.go
index eed09bf50..ca8599d7c 100644
--- a/swarm/network/simulation/simulation_test.go
+++ b/swarm/network/simulation/simulation_test.go
@@ -205,3 +205,16 @@ func (t *noopService) Start(server *p2p.Server) error {
 func (t *noopService) Stop() error {
 	return nil
 }
+
+// a helper function for most basic noop service
+// of a different type then noopService to test
+// multiple services on one node.
+func noopService2Func(ctx *adapters.ServiceContext, b *sync.Map) (node.Service, func(), error) {
+	return new(noopService2), nil, nil
+}
+
+// noopService2 is the service that does not do anything
+// but implements node.Service interface.
+type noopService2 struct {
+	noopService
+}
diff --git a/swarm/network/stream/delivery.go b/swarm/network/stream/delivery.go
index 64d754336..a5c9fa7e8 100644
--- a/swarm/network/stream/delivery.go
+++ b/swarm/network/stream/delivery.go
@@ -255,7 +255,7 @@ func (d *Delivery) RequestFromPeers(ctx context.Context, req *network.Request) (
 			}
 			sp = d.getPeer(id)
 			if sp == nil {
-				log.Warn("Delivery.RequestFromPeers: peer not found", "id", id)
+				//log.Warn("Delivery.RequestFromPeers: peer not found", "id", id)
 				return true
 			}
 			spID = &id
-- 
GitLab