| 
									
										
										
										
											2014-12-12 22:23:42 +01:00
										 |  |  | package whisper | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"testing" | 
					
						
							|  |  |  | 	"time" | 
					
						
							| 
									
										
										
										
											2015-04-13 13:15:01 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	"github.com/ethereum/go-ethereum/p2p" | 
					
						
							| 
									
										
										
										
											2015-04-15 12:50:10 +03:00
										 |  |  | 	"github.com/ethereum/go-ethereum/p2p/discover" | 
					
						
							| 
									
										
										
										
											2014-12-12 22:23:42 +01:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-14 19:00:57 +03:00
										 |  |  | func startTestCluster(n int) []*Whisper { | 
					
						
							|  |  |  | 	// Create the batch of simulated peers | 
					
						
							|  |  |  | 	nodes := make([]*p2p.Peer, n) | 
					
						
							| 
									
										
										
										
											2015-04-13 13:15:01 +03:00
										 |  |  | 	for i := 0; i < n; i++ { | 
					
						
							| 
									
										
										
										
											2015-04-15 12:50:10 +03:00
										 |  |  | 		nodes[i] = p2p.NewPeer(discover.NodeID{}, "", nil) | 
					
						
							| 
									
										
										
										
											2015-04-13 13:15:01 +03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-04-14 19:00:57 +03:00
										 |  |  | 	whispers := make([]*Whisper, n) | 
					
						
							|  |  |  | 	for i := 0; i < n; i++ { | 
					
						
							|  |  |  | 		whispers[i] = New() | 
					
						
							|  |  |  | 		whispers[i].Start() | 
					
						
							| 
									
										
										
										
											2015-04-13 16:19:34 +03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-04-14 19:00:57 +03:00
										 |  |  | 	// Wire all the peers to the root one | 
					
						
							|  |  |  | 	for i := 1; i < n; i++ { | 
					
						
							| 
									
										
										
										
											2015-04-15 13:01:22 +03:00
										 |  |  | 		src, dst := p2p.MsgPipe() | 
					
						
							| 
									
										
										
										
											2015-04-13 13:15:01 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-14 19:00:57 +03:00
										 |  |  | 		go whispers[0].handlePeer(nodes[i], src) | 
					
						
							|  |  |  | 		go whispers[i].handlePeer(nodes[0], dst) | 
					
						
							| 
									
										
										
										
											2015-04-13 13:15:01 +03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-04-14 19:00:57 +03:00
										 |  |  | 	return whispers | 
					
						
							| 
									
										
										
										
											2015-04-13 13:15:01 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestSelfMessage(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2015-04-13 16:19:34 +03:00
										 |  |  | 	// Start the single node cluster | 
					
						
							| 
									
										
										
										
											2015-04-14 19:00:57 +03:00
										 |  |  | 	client := startTestCluster(1)[0] | 
					
						
							| 
									
										
										
										
											2015-04-13 13:15:01 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Start watching for self messages, signal any arrivals | 
					
						
							|  |  |  | 	self := client.NewIdentity() | 
					
						
							|  |  |  | 	done := make(chan struct{}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	client.Watch(Filter{ | 
					
						
							|  |  |  | 		To: &self.PublicKey, | 
					
						
							| 
									
										
										
										
											2014-12-12 22:23:42 +01:00
										 |  |  | 		Fn: func(msg *Message) { | 
					
						
							| 
									
										
										
										
											2015-04-13 13:15:01 +03:00
										 |  |  | 			close(done) | 
					
						
							| 
									
										
										
										
											2014-12-12 22:23:42 +01:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 	}) | 
					
						
							| 
									
										
										
										
											2015-04-13 13:15:01 +03:00
										 |  |  | 	// Send a dummy message to oneself | 
					
						
							| 
									
										
										
										
											2015-04-14 12:12:47 +03:00
										 |  |  | 	msg := NewMessage([]byte("self whisper")) | 
					
						
							| 
									
										
										
										
											2015-04-14 15:16:02 +03:00
										 |  |  | 	envelope, err := msg.Wrap(DefaultPoW, Options{ | 
					
						
							| 
									
										
										
										
											2015-04-13 13:15:01 +03:00
										 |  |  | 		From: self, | 
					
						
							|  |  |  | 		To:   &self.PublicKey, | 
					
						
							| 
									
										
										
										
											2015-04-14 15:16:02 +03:00
										 |  |  | 		TTL:  DefaultTTL, | 
					
						
							| 
									
										
										
										
											2014-12-12 22:23:42 +01:00
										 |  |  | 	}) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2015-04-13 13:15:01 +03:00
										 |  |  | 		t.Fatalf("failed to wrap message: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// Dump the message into the system and wait for it to pop back out | 
					
						
							|  |  |  | 	if err := client.Send(envelope); err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("failed to send self-message: %v", err) | 
					
						
							| 
									
										
										
										
											2014-12-12 22:23:42 +01:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-04-13 13:15:01 +03:00
										 |  |  | 	select { | 
					
						
							|  |  |  | 	case <-done: | 
					
						
							|  |  |  | 	case <-time.After(time.Second): | 
					
						
							|  |  |  | 		t.Fatalf("self-message receive timeout") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2014-12-12 22:23:42 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-13 13:15:01 +03:00
										 |  |  | func TestDirectMessage(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2015-04-13 16:19:34 +03:00
										 |  |  | 	// Start the sender-recipient cluster | 
					
						
							| 
									
										
										
										
											2015-04-14 19:00:57 +03:00
										 |  |  | 	cluster := startTestCluster(2) | 
					
						
							| 
									
										
										
										
											2015-04-13 13:15:01 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-14 19:00:57 +03:00
										 |  |  | 	sender := cluster[0] | 
					
						
							| 
									
										
										
										
											2015-04-13 13:15:01 +03:00
										 |  |  | 	senderId := sender.NewIdentity() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-14 19:00:57 +03:00
										 |  |  | 	recipient := cluster[1] | 
					
						
							| 
									
										
										
										
											2015-04-13 13:15:01 +03:00
										 |  |  | 	recipientId := recipient.NewIdentity() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Watch for arriving messages on the recipient | 
					
						
							|  |  |  | 	done := make(chan struct{}) | 
					
						
							|  |  |  | 	recipient.Watch(Filter{ | 
					
						
							|  |  |  | 		To: &recipientId.PublicKey, | 
					
						
							|  |  |  | 		Fn: func(msg *Message) { | 
					
						
							|  |  |  | 			close(done) | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 	// Send a dummy message from the sender | 
					
						
							| 
									
										
										
										
											2015-04-14 12:12:47 +03:00
										 |  |  | 	msg := NewMessage([]byte("direct whisper")) | 
					
						
							| 
									
										
										
										
											2015-04-14 15:16:02 +03:00
										 |  |  | 	envelope, err := msg.Wrap(DefaultPoW, Options{ | 
					
						
							| 
									
										
										
										
											2015-04-13 13:15:01 +03:00
										 |  |  | 		From: senderId, | 
					
						
							|  |  |  | 		To:   &recipientId.PublicKey, | 
					
						
							| 
									
										
										
										
											2015-04-14 15:16:02 +03:00
										 |  |  | 		TTL:  DefaultTTL, | 
					
						
							| 
									
										
										
										
											2015-04-13 13:15:01 +03:00
										 |  |  | 	}) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("failed to wrap message: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if err := sender.Send(envelope); err != nil { | 
					
						
							| 
									
										
										
										
											2015-04-14 12:12:47 +03:00
										 |  |  | 		t.Fatalf("failed to send direct message: %v", err) | 
					
						
							| 
									
										
										
										
											2015-04-13 13:15:01 +03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	// Wait for an arrival or a timeout | 
					
						
							| 
									
										
										
										
											2014-12-12 22:23:42 +01:00
										 |  |  | 	select { | 
					
						
							| 
									
										
										
										
											2015-04-13 13:15:01 +03:00
										 |  |  | 	case <-done: | 
					
						
							|  |  |  | 	case <-time.After(time.Second): | 
					
						
							|  |  |  | 		t.Fatalf("direct message receive timeout") | 
					
						
							| 
									
										
										
										
											2014-12-12 22:23:42 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2015-04-14 12:12:47 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | func TestAnonymousBroadcast(t *testing.T) { | 
					
						
							|  |  |  | 	testBroadcast(true, t) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestIdentifiedBroadcast(t *testing.T) { | 
					
						
							|  |  |  | 	testBroadcast(false, t) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func testBroadcast(anonymous bool, t *testing.T) { | 
					
						
							|  |  |  | 	// Start the single sender multi recipient cluster | 
					
						
							| 
									
										
										
										
											2015-04-14 19:00:57 +03:00
										 |  |  | 	cluster := startTestCluster(3) | 
					
						
							| 
									
										
										
										
											2015-04-14 12:12:47 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-14 19:00:57 +03:00
										 |  |  | 	sender := cluster[1] | 
					
						
							|  |  |  | 	targets := cluster[1:] | 
					
						
							|  |  |  | 	for _, target := range targets { | 
					
						
							| 
									
										
										
										
											2015-04-14 12:12:47 +03:00
										 |  |  | 		if !anonymous { | 
					
						
							| 
									
										
										
										
											2015-04-14 19:00:57 +03:00
										 |  |  | 			target.NewIdentity() | 
					
						
							| 
									
										
										
										
											2015-04-14 12:12:47 +03:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// Watch for arriving messages on the recipients | 
					
						
							|  |  |  | 	dones := make([]chan struct{}, len(targets)) | 
					
						
							|  |  |  | 	for i := 0; i < len(targets); i++ { | 
					
						
							|  |  |  | 		done := make(chan struct{}) // need for the closure | 
					
						
							|  |  |  | 		dones[i] = done | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		targets[i].Watch(Filter{ | 
					
						
							| 
									
										
										
										
											2015-04-22 12:50:48 +03:00
										 |  |  | 			Topics: NewFilterTopicsFromStringsFlat("broadcast topic"), | 
					
						
							| 
									
										
										
										
											2015-04-14 12:12:47 +03:00
										 |  |  | 			Fn: func(msg *Message) { | 
					
						
							|  |  |  | 				close(done) | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// Send a dummy message from the sender | 
					
						
							|  |  |  | 	msg := NewMessage([]byte("broadcast whisper")) | 
					
						
							| 
									
										
										
										
											2015-04-14 15:16:02 +03:00
										 |  |  | 	envelope, err := msg.Wrap(DefaultPoW, Options{ | 
					
						
							| 
									
										
										
										
											2015-04-14 12:12:47 +03:00
										 |  |  | 		Topics: NewTopicsFromStrings("broadcast topic"), | 
					
						
							| 
									
										
										
										
											2015-04-14 15:16:02 +03:00
										 |  |  | 		TTL:    DefaultTTL, | 
					
						
							| 
									
										
										
										
											2015-04-14 12:12:47 +03:00
										 |  |  | 	}) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("failed to wrap message: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if err := sender.Send(envelope); err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("failed to send broadcast message: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// Wait for an arrival on each recipient, or timeouts | 
					
						
							|  |  |  | 	timeout := time.After(time.Second) | 
					
						
							|  |  |  | 	for _, done := range dones { | 
					
						
							|  |  |  | 		select { | 
					
						
							|  |  |  | 		case <-done: | 
					
						
							|  |  |  | 		case <-timeout: | 
					
						
							|  |  |  | 			t.Fatalf("broadcast message receive timeout") | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2015-04-15 10:50:31 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | func TestMessageExpiration(t *testing.T) { | 
					
						
							|  |  |  | 	// Start the single node cluster and inject a dummy message | 
					
						
							|  |  |  | 	node := startTestCluster(1)[0] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	message := NewMessage([]byte("expiring message")) | 
					
						
							|  |  |  | 	envelope, err := message.Wrap(DefaultPoW, Options{ | 
					
						
							|  |  |  | 		TTL: time.Second, | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("failed to wrap message: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if err := node.Send(envelope); err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("failed to inject message: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// Check that the message is inside the cache | 
					
						
							|  |  |  | 	if _, ok := node.messages[envelope.Hash()]; !ok { | 
					
						
							|  |  |  | 		t.Fatalf("message not found in cache") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// Wait for expiration and check cache again | 
					
						
							|  |  |  | 	time.Sleep(time.Second)     // wait for expiration | 
					
						
							| 
									
										
										
										
											2015-04-16 11:20:01 +03:00
										 |  |  | 	time.Sleep(expirationCycle) // wait for cleanup cycle | 
					
						
							| 
									
										
										
										
											2015-04-15 10:50:31 +03:00
										 |  |  | 	if _, ok := node.messages[envelope.Hash()]; ok { | 
					
						
							|  |  |  | 		t.Fatalf("message not expired from cache") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } |