github.com/ethereumproject/go-ethereum@v5.5.2+incompatible/whisper/whisper_test.go (about)

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