github.com/SmartMeshFoundation/Spectrum@v0.0.0-20220621030607-452a266fee1e/whisper/whisperv2/whisper_test.go (about)

     1  // Copyright 2014 The Spectrum Authors
     2  // This file is part of the Spectrum library.
     3  //
     4  // The Spectrum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The Spectrum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the Spectrum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package whisperv2
    18  
    19  import (
    20  	"testing"
    21  	"time"
    22  
    23  	"github.com/SmartMeshFoundation/Spectrum/p2p"
    24  	"github.com/SmartMeshFoundation/Spectrum/p2p/discover"
    25  )
    26  
    27  func startTestCluster(n int) []*Whisper {
    28  	// Create the batch of simulated peers
    29  	nodes := make([]*p2p.Peer, n)
    30  	for i := 0; i < n; i++ {
    31  		nodes[i] = p2p.NewPeer(discover.NodeID{}, "", nil)
    32  	}
    33  	whispers := make([]*Whisper, n)
    34  	for i := 0; i < n; i++ {
    35  		whispers[i] = New()
    36  		whispers[i].Start(nil)
    37  	}
    38  	// Wire all the peers to the root one
    39  	for i := 1; i < n; i++ {
    40  		src, dst := p2p.MsgPipe()
    41  
    42  		go whispers[0].handlePeer(nodes[i], src)
    43  		go whispers[i].handlePeer(nodes[0], dst)
    44  	}
    45  	return whispers
    46  }
    47  
    48  func TestSelfMessage(t *testing.T) {
    49  	// Start the single node cluster
    50  	client := startTestCluster(1)[0]
    51  
    52  	// Start watching for self messages, signal any arrivals
    53  	self := client.NewIdentity()
    54  	done := make(chan struct{})
    55  
    56  	client.Watch(Filter{
    57  		To: &self.PublicKey,
    58  		Fn: func(msg *Message) {
    59  			close(done)
    60  		},
    61  	})
    62  	// Send a dummy message to oneself
    63  	msg := NewMessage([]byte("self whisper"))
    64  	envelope, err := msg.Wrap(DefaultPoW, Options{
    65  		From: self,
    66  		To:   &self.PublicKey,
    67  		TTL:  DefaultTTL,
    68  	})
    69  	if err != nil {
    70  		t.Fatalf("failed to wrap message: %v", err)
    71  	}
    72  	// Dump the message into the system and wait for it to pop back out
    73  	if err := client.Send(envelope); err != nil {
    74  		t.Fatalf("failed to send self-message: %v", err)
    75  	}
    76  	select {
    77  	case <-done:
    78  	case <-time.After(time.Second):
    79  		t.Fatalf("self-message receive timeout")
    80  	}
    81  }
    82  
    83  func TestDirectMessage(t *testing.T) {
    84  	// Start the sender-recipient cluster
    85  	cluster := startTestCluster(2)
    86  
    87  	sender := cluster[0]
    88  	senderId := sender.NewIdentity()
    89  
    90  	recipient := cluster[1]
    91  	recipientId := recipient.NewIdentity()
    92  
    93  	// Watch for arriving messages on the recipient
    94  	done := make(chan struct{})
    95  	recipient.Watch(Filter{
    96  		To: &recipientId.PublicKey,
    97  		Fn: func(msg *Message) {
    98  			close(done)
    99  		},
   100  	})
   101  	// Send a dummy message from the sender
   102  	msg := NewMessage([]byte("direct whisper"))
   103  	envelope, err := msg.Wrap(DefaultPoW, Options{
   104  		From: senderId,
   105  		To:   &recipientId.PublicKey,
   106  		TTL:  DefaultTTL,
   107  	})
   108  	if err != nil {
   109  		t.Fatalf("failed to wrap message: %v", err)
   110  	}
   111  	if err := sender.Send(envelope); err != nil {
   112  		t.Fatalf("failed to send direct message: %v", err)
   113  	}
   114  	// Wait for an arrival or a timeout
   115  	select {
   116  	case <-done:
   117  	case <-time.After(time.Second):
   118  		t.Fatalf("direct message receive timeout")
   119  	}
   120  }
   121  
   122  func TestAnonymousBroadcast(t *testing.T) {
   123  	testBroadcast(true, t)
   124  }
   125  
   126  func TestIdentifiedBroadcast(t *testing.T) {
   127  	testBroadcast(false, t)
   128  }
   129  
   130  func testBroadcast(anonymous bool, t *testing.T) {
   131  	// Start the single sender multi recipient cluster
   132  	cluster := startTestCluster(3)
   133  
   134  	sender := cluster[1]
   135  	targets := cluster[1:]
   136  	for _, target := range targets {
   137  		if !anonymous {
   138  			target.NewIdentity()
   139  		}
   140  	}
   141  	// Watch for arriving messages on the recipients
   142  	dones := make([]chan struct{}, len(targets))
   143  	for i := 0; i < len(targets); i++ {
   144  		done := make(chan struct{}) // need for the closure
   145  		dones[i] = done
   146  
   147  		targets[i].Watch(Filter{
   148  			Topics: NewFilterTopicsFromStringsFlat("broadcast topic"),
   149  			Fn: func(msg *Message) {
   150  				close(done)
   151  			},
   152  		})
   153  	}
   154  	// Send a dummy message from the sender
   155  	msg := NewMessage([]byte("broadcast whisper"))
   156  	envelope, err := msg.Wrap(DefaultPoW, Options{
   157  		Topics: NewTopicsFromStrings("broadcast topic"),
   158  		TTL:    DefaultTTL,
   159  	})
   160  	if err != nil {
   161  		t.Fatalf("failed to wrap message: %v", err)
   162  	}
   163  	if err := sender.Send(envelope); err != nil {
   164  		t.Fatalf("failed to send broadcast message: %v", err)
   165  	}
   166  	// Wait for an arrival on each recipient, or timeouts
   167  	timeout := time.After(time.Second)
   168  	for _, done := range dones {
   169  		select {
   170  		case <-done:
   171  		case <-timeout:
   172  			t.Fatalf("broadcast message receive timeout")
   173  		}
   174  	}
   175  }
   176  
   177  func TestMessageExpiration(t *testing.T) {
   178  	// Start the single node cluster and inject a dummy message
   179  	node := startTestCluster(1)[0]
   180  
   181  	message := NewMessage([]byte("expiring message"))
   182  	envelope, err := message.Wrap(DefaultPoW, Options{TTL: time.Second})
   183  	if err != nil {
   184  		t.Fatalf("failed to wrap message: %v", err)
   185  	}
   186  	if err := node.Send(envelope); err != nil {
   187  		t.Fatalf("failed to inject message: %v", err)
   188  	}
   189  	// Check that the message is inside the cache
   190  	node.poolMu.RLock()
   191  	_, found := node.messages[envelope.Hash()]
   192  	node.poolMu.RUnlock()
   193  
   194  	if !found {
   195  		t.Fatalf("message not found in cache")
   196  	}
   197  	// Wait for expiration and check cache again
   198  	time.Sleep(time.Second)         // wait for expiration
   199  	time.Sleep(2 * expirationCycle) // wait for cleanup cycle
   200  
   201  	node.poolMu.RLock()
   202  	_, found = node.messages[envelope.Hash()]
   203  	node.poolMu.RUnlock()
   204  	if found {
   205  		t.Fatalf("message not expired from cache")
   206  	}
   207  
   208  	// Check that adding an expired envelope doesn't do anything.
   209  	node.add(envelope)
   210  	node.poolMu.RLock()
   211  	_, found = node.messages[envelope.Hash()]
   212  	node.poolMu.RUnlock()
   213  	if found {
   214  		t.Fatalf("message was added to cache")
   215  	}
   216  }