github.com/shyftnetwork/go-empyrean@v1.8.3-0.20191127201940-fbfca9338f04/swarm/network/stream/streamer_test.go (about)

     1  // Copyright 2018 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  package stream
    18  
    19  import (
    20  	"bytes"
    21  	"context"
    22  	"errors"
    23  	"fmt"
    24  	"strconv"
    25  	"testing"
    26  	"time"
    27  
    28  	"github.com/ShyftNetwork/go-empyrean/common"
    29  	"github.com/ShyftNetwork/go-empyrean/log"
    30  	"github.com/ShyftNetwork/go-empyrean/p2p/enode"
    31  	p2ptest "github.com/ShyftNetwork/go-empyrean/p2p/testing"
    32  	"github.com/ShyftNetwork/go-empyrean/swarm/network"
    33  	"golang.org/x/crypto/sha3"
    34  )
    35  
    36  func TestStreamerSubscribe(t *testing.T) {
    37  	tester, streamer, _, teardown, err := newStreamerTester(t, nil)
    38  	defer teardown()
    39  	if err != nil {
    40  		t.Fatal(err)
    41  	}
    42  
    43  	stream := NewStream("foo", "", true)
    44  	err = streamer.Subscribe(tester.Nodes[0].ID(), stream, NewRange(0, 0), Top)
    45  	if err == nil || err.Error() != "stream foo not registered" {
    46  		t.Fatalf("Expected error %v, got %v", "stream foo not registered", err)
    47  	}
    48  }
    49  
    50  func TestStreamerRequestSubscription(t *testing.T) {
    51  	tester, streamer, _, teardown, err := newStreamerTester(t, nil)
    52  	defer teardown()
    53  	if err != nil {
    54  		t.Fatal(err)
    55  	}
    56  
    57  	stream := NewStream("foo", "", false)
    58  	err = streamer.RequestSubscription(tester.Nodes[0].ID(), stream, &Range{}, Top)
    59  	if err == nil || err.Error() != "stream foo not registered" {
    60  		t.Fatalf("Expected error %v, got %v", "stream foo not registered", err)
    61  	}
    62  }
    63  
    64  var (
    65  	hash0         = sha3.Sum256([]byte{0})
    66  	hash1         = sha3.Sum256([]byte{1})
    67  	hash2         = sha3.Sum256([]byte{2})
    68  	hashesTmp     = append(hash0[:], hash1[:]...)
    69  	hashes        = append(hashesTmp, hash2[:]...)
    70  	corruptHashes = append(hashes[:40])
    71  )
    72  
    73  type testClient struct {
    74  	t              string
    75  	wait0          chan bool
    76  	wait2          chan bool
    77  	batchDone      chan bool
    78  	receivedHashes map[string][]byte
    79  }
    80  
    81  func newTestClient(t string) *testClient {
    82  	return &testClient{
    83  		t:              t,
    84  		wait0:          make(chan bool),
    85  		wait2:          make(chan bool),
    86  		batchDone:      make(chan bool),
    87  		receivedHashes: make(map[string][]byte),
    88  	}
    89  }
    90  
    91  func (self *testClient) NeedData(ctx context.Context, hash []byte) func(context.Context) error {
    92  	self.receivedHashes[string(hash)] = hash
    93  	if bytes.Equal(hash, hash0[:]) {
    94  		return func(context.Context) error {
    95  			<-self.wait0
    96  			return nil
    97  		}
    98  	} else if bytes.Equal(hash, hash2[:]) {
    99  		return func(context.Context) error {
   100  			<-self.wait2
   101  			return nil
   102  		}
   103  	}
   104  	return nil
   105  }
   106  
   107  func (self *testClient) BatchDone(Stream, uint64, []byte, []byte) func() (*TakeoverProof, error) {
   108  	close(self.batchDone)
   109  	return nil
   110  }
   111  
   112  func (self *testClient) Close() {}
   113  
   114  type testServer struct {
   115  	t            string
   116  	sessionIndex uint64
   117  }
   118  
   119  func newTestServer(t string, sessionIndex uint64) *testServer {
   120  	return &testServer{
   121  		t:            t,
   122  		sessionIndex: sessionIndex,
   123  	}
   124  }
   125  
   126  func (s *testServer) SessionIndex() (uint64, error) {
   127  	return s.sessionIndex, nil
   128  }
   129  
   130  func (self *testServer) SetNextBatch(from uint64, to uint64) ([]byte, uint64, uint64, *HandoverProof, error) {
   131  	return make([]byte, HashSize), from + 1, to + 1, nil, nil
   132  }
   133  
   134  func (self *testServer) GetData(context.Context, []byte) ([]byte, error) {
   135  	return nil, nil
   136  }
   137  
   138  func (self *testServer) Close() {
   139  }
   140  
   141  func TestStreamerDownstreamSubscribeUnsubscribeMsgExchange(t *testing.T) {
   142  	tester, streamer, _, teardown, err := newStreamerTester(t, nil)
   143  	defer teardown()
   144  	if err != nil {
   145  		t.Fatal(err)
   146  	}
   147  
   148  	streamer.RegisterClientFunc("foo", func(p *Peer, t string, live bool) (Client, error) {
   149  		return newTestClient(t), nil
   150  	})
   151  
   152  	node := tester.Nodes[0]
   153  
   154  	stream := NewStream("foo", "", true)
   155  	err = streamer.Subscribe(node.ID(), stream, NewRange(5, 8), Top)
   156  	if err != nil {
   157  		t.Fatalf("Expected no error, got %v", err)
   158  	}
   159  
   160  	err = tester.TestExchanges(
   161  		p2ptest.Exchange{
   162  			Label: "Subscribe message",
   163  			Expects: []p2ptest.Expect{
   164  				{
   165  					Code: 4,
   166  					Msg: &SubscribeMsg{
   167  						Stream:   stream,
   168  						History:  NewRange(5, 8),
   169  						Priority: Top,
   170  					},
   171  					Peer: node.ID(),
   172  				},
   173  			},
   174  		},
   175  		// trigger OfferedHashesMsg to actually create the client
   176  		p2ptest.Exchange{
   177  			Label: "OfferedHashes message",
   178  			Triggers: []p2ptest.Trigger{
   179  				{
   180  					Code: 1,
   181  					Msg: &OfferedHashesMsg{
   182  						HandoverProof: &HandoverProof{
   183  							Handover: &Handover{},
   184  						},
   185  						Hashes: hashes,
   186  						From:   5,
   187  						To:     8,
   188  						Stream: stream,
   189  					},
   190  					Peer: node.ID(),
   191  				},
   192  			},
   193  			Expects: []p2ptest.Expect{
   194  				{
   195  					Code: 2,
   196  					Msg: &WantedHashesMsg{
   197  						Stream: stream,
   198  						Want:   []byte{5},
   199  						From:   9,
   200  						To:     0,
   201  					},
   202  					Peer: node.ID(),
   203  				},
   204  			},
   205  		},
   206  	)
   207  	if err != nil {
   208  		t.Fatal(err)
   209  	}
   210  
   211  	err = streamer.Unsubscribe(node.ID(), stream)
   212  	if err != nil {
   213  		t.Fatalf("Expected no error, got %v", err)
   214  	}
   215  
   216  	err = tester.TestExchanges(p2ptest.Exchange{
   217  		Label: "Unsubscribe message",
   218  		Expects: []p2ptest.Expect{
   219  			{
   220  				Code: 0,
   221  				Msg: &UnsubscribeMsg{
   222  					Stream: stream,
   223  				},
   224  				Peer: node.ID(),
   225  			},
   226  		},
   227  	})
   228  
   229  	if err != nil {
   230  		t.Fatal(err)
   231  	}
   232  }
   233  
   234  func TestStreamerUpstreamSubscribeUnsubscribeMsgExchange(t *testing.T) {
   235  	tester, streamer, _, teardown, err := newStreamerTester(t, nil)
   236  	defer teardown()
   237  	if err != nil {
   238  		t.Fatal(err)
   239  	}
   240  
   241  	stream := NewStream("foo", "", false)
   242  
   243  	streamer.RegisterServerFunc("foo", func(p *Peer, t string, live bool) (Server, error) {
   244  		return newTestServer(t, 10), nil
   245  	})
   246  
   247  	node := tester.Nodes[0]
   248  
   249  	err = tester.TestExchanges(p2ptest.Exchange{
   250  		Label: "Subscribe message",
   251  		Triggers: []p2ptest.Trigger{
   252  			{
   253  				Code: 4,
   254  				Msg: &SubscribeMsg{
   255  					Stream:   stream,
   256  					History:  NewRange(5, 8),
   257  					Priority: Top,
   258  				},
   259  				Peer: node.ID(),
   260  			},
   261  		},
   262  		Expects: []p2ptest.Expect{
   263  			{
   264  				Code: 1,
   265  				Msg: &OfferedHashesMsg{
   266  					Stream: stream,
   267  					HandoverProof: &HandoverProof{
   268  						Handover: &Handover{},
   269  					},
   270  					Hashes: make([]byte, HashSize),
   271  					From:   6,
   272  					To:     9,
   273  				},
   274  				Peer: node.ID(),
   275  			},
   276  		},
   277  	})
   278  
   279  	if err != nil {
   280  		t.Fatal(err)
   281  	}
   282  
   283  	err = tester.TestExchanges(p2ptest.Exchange{
   284  		Label: "unsubscribe message",
   285  		Triggers: []p2ptest.Trigger{
   286  			{
   287  				Code: 0,
   288  				Msg: &UnsubscribeMsg{
   289  					Stream: stream,
   290  				},
   291  				Peer: node.ID(),
   292  			},
   293  		},
   294  	})
   295  
   296  	if err != nil {
   297  		t.Fatal(err)
   298  	}
   299  }
   300  
   301  func TestStreamerUpstreamSubscribeUnsubscribeMsgExchangeLive(t *testing.T) {
   302  	tester, streamer, _, teardown, err := newStreamerTester(t, nil)
   303  	defer teardown()
   304  	if err != nil {
   305  		t.Fatal(err)
   306  	}
   307  
   308  	stream := NewStream("foo", "", true)
   309  
   310  	streamer.RegisterServerFunc("foo", func(p *Peer, t string, live bool) (Server, error) {
   311  		return newTestServer(t, 0), nil
   312  	})
   313  
   314  	node := tester.Nodes[0]
   315  
   316  	err = tester.TestExchanges(p2ptest.Exchange{
   317  		Label: "Subscribe message",
   318  		Triggers: []p2ptest.Trigger{
   319  			{
   320  				Code: 4,
   321  				Msg: &SubscribeMsg{
   322  					Stream:   stream,
   323  					Priority: Top,
   324  				},
   325  				Peer: node.ID(),
   326  			},
   327  		},
   328  		Expects: []p2ptest.Expect{
   329  			{
   330  				Code: 1,
   331  				Msg: &OfferedHashesMsg{
   332  					Stream: stream,
   333  					HandoverProof: &HandoverProof{
   334  						Handover: &Handover{},
   335  					},
   336  					Hashes: make([]byte, HashSize),
   337  					From:   1,
   338  					To:     0,
   339  				},
   340  				Peer: node.ID(),
   341  			},
   342  		},
   343  	})
   344  
   345  	if err != nil {
   346  		t.Fatal(err)
   347  	}
   348  
   349  	err = tester.TestExchanges(p2ptest.Exchange{
   350  		Label: "unsubscribe message",
   351  		Triggers: []p2ptest.Trigger{
   352  			{
   353  				Code: 0,
   354  				Msg: &UnsubscribeMsg{
   355  					Stream: stream,
   356  				},
   357  				Peer: node.ID(),
   358  			},
   359  		},
   360  	})
   361  
   362  	if err != nil {
   363  		t.Fatal(err)
   364  	}
   365  }
   366  
   367  func TestStreamerUpstreamSubscribeErrorMsgExchange(t *testing.T) {
   368  	tester, streamer, _, teardown, err := newStreamerTester(t, nil)
   369  	defer teardown()
   370  	if err != nil {
   371  		t.Fatal(err)
   372  	}
   373  
   374  	streamer.RegisterServerFunc("foo", func(p *Peer, t string, live bool) (Server, error) {
   375  		return newTestServer(t, 0), nil
   376  	})
   377  
   378  	stream := NewStream("bar", "", true)
   379  
   380  	node := tester.Nodes[0]
   381  
   382  	err = tester.TestExchanges(p2ptest.Exchange{
   383  		Label: "Subscribe message",
   384  		Triggers: []p2ptest.Trigger{
   385  			{
   386  				Code: 4,
   387  				Msg: &SubscribeMsg{
   388  					Stream:   stream,
   389  					History:  NewRange(5, 8),
   390  					Priority: Top,
   391  				},
   392  				Peer: node.ID(),
   393  			},
   394  		},
   395  		Expects: []p2ptest.Expect{
   396  			{
   397  				Code: 7,
   398  				Msg: &SubscribeErrorMsg{
   399  					Error: "stream bar not registered",
   400  				},
   401  				Peer: node.ID(),
   402  			},
   403  		},
   404  	})
   405  
   406  	if err != nil {
   407  		t.Fatal(err)
   408  	}
   409  }
   410  
   411  func TestStreamerUpstreamSubscribeLiveAndHistory(t *testing.T) {
   412  	tester, streamer, _, teardown, err := newStreamerTester(t, nil)
   413  	defer teardown()
   414  	if err != nil {
   415  		t.Fatal(err)
   416  	}
   417  
   418  	stream := NewStream("foo", "", true)
   419  
   420  	streamer.RegisterServerFunc("foo", func(p *Peer, t string, live bool) (Server, error) {
   421  		return newTestServer(t, 10), nil
   422  	})
   423  
   424  	node := tester.Nodes[0]
   425  
   426  	err = tester.TestExchanges(p2ptest.Exchange{
   427  		Label: "Subscribe message",
   428  		Triggers: []p2ptest.Trigger{
   429  			{
   430  				Code: 4,
   431  				Msg: &SubscribeMsg{
   432  					Stream:   stream,
   433  					History:  NewRange(5, 8),
   434  					Priority: Top,
   435  				},
   436  				Peer: node.ID(),
   437  			},
   438  		},
   439  		Expects: []p2ptest.Expect{
   440  			{
   441  				Code: 1,
   442  				Msg: &OfferedHashesMsg{
   443  					Stream: NewStream("foo", "", false),
   444  					HandoverProof: &HandoverProof{
   445  						Handover: &Handover{},
   446  					},
   447  					Hashes: make([]byte, HashSize),
   448  					From:   6,
   449  					To:     9,
   450  				},
   451  				Peer: node.ID(),
   452  			},
   453  			{
   454  				Code: 1,
   455  				Msg: &OfferedHashesMsg{
   456  					Stream: stream,
   457  					HandoverProof: &HandoverProof{
   458  						Handover: &Handover{},
   459  					},
   460  					From:   11,
   461  					To:     0,
   462  					Hashes: make([]byte, HashSize),
   463  				},
   464  				Peer: node.ID(),
   465  			},
   466  		},
   467  	})
   468  
   469  	if err != nil {
   470  		t.Fatal(err)
   471  	}
   472  }
   473  
   474  func TestStreamerDownstreamCorruptHashesMsgExchange(t *testing.T) {
   475  	tester, streamer, _, teardown, err := newStreamerTester(t, nil)
   476  	defer teardown()
   477  	if err != nil {
   478  		t.Fatal(err)
   479  	}
   480  
   481  	stream := NewStream("foo", "", true)
   482  
   483  	var tc *testClient
   484  
   485  	streamer.RegisterClientFunc("foo", func(p *Peer, t string, live bool) (Client, error) {
   486  		tc = newTestClient(t)
   487  		return tc, nil
   488  	})
   489  
   490  	node := tester.Nodes[0]
   491  
   492  	err = streamer.Subscribe(node.ID(), stream, NewRange(5, 8), Top)
   493  	if err != nil {
   494  		t.Fatalf("Expected no error, got %v", err)
   495  	}
   496  
   497  	err = tester.TestExchanges(p2ptest.Exchange{
   498  		Label: "Subscribe message",
   499  		Expects: []p2ptest.Expect{
   500  			{
   501  				Code: 4,
   502  				Msg: &SubscribeMsg{
   503  					Stream:   stream,
   504  					History:  NewRange(5, 8),
   505  					Priority: Top,
   506  				},
   507  				Peer: node.ID(),
   508  			},
   509  		},
   510  	},
   511  		p2ptest.Exchange{
   512  			Label: "Corrupt offered hash message",
   513  			Triggers: []p2ptest.Trigger{
   514  				{
   515  					Code: 1,
   516  					Msg: &OfferedHashesMsg{
   517  						HandoverProof: &HandoverProof{
   518  							Handover: &Handover{},
   519  						},
   520  						Hashes: corruptHashes,
   521  						From:   5,
   522  						To:     8,
   523  						Stream: stream,
   524  					},
   525  					Peer: node.ID(),
   526  				},
   527  			},
   528  		})
   529  	if err != nil {
   530  		t.Fatal(err)
   531  	}
   532  
   533  	expectedError := errors.New("Message handler error: (msg code 1): error invalid hashes length (len: 40)")
   534  	if err := tester.TestDisconnected(&p2ptest.Disconnect{Peer: node.ID(), Error: expectedError}); err != nil {
   535  		t.Fatal(err)
   536  	}
   537  }
   538  
   539  func TestStreamerDownstreamOfferedHashesMsgExchange(t *testing.T) {
   540  	tester, streamer, _, teardown, err := newStreamerTester(t, nil)
   541  	defer teardown()
   542  	if err != nil {
   543  		t.Fatal(err)
   544  	}
   545  
   546  	stream := NewStream("foo", "", true)
   547  
   548  	var tc *testClient
   549  
   550  	streamer.RegisterClientFunc("foo", func(p *Peer, t string, live bool) (Client, error) {
   551  		tc = newTestClient(t)
   552  		return tc, nil
   553  	})
   554  
   555  	node := tester.Nodes[0]
   556  
   557  	err = streamer.Subscribe(node.ID(), stream, NewRange(5, 8), Top)
   558  	if err != nil {
   559  		t.Fatalf("Expected no error, got %v", err)
   560  	}
   561  
   562  	err = tester.TestExchanges(p2ptest.Exchange{
   563  		Label: "Subscribe message",
   564  		Expects: []p2ptest.Expect{
   565  			{
   566  				Code: 4,
   567  				Msg: &SubscribeMsg{
   568  					Stream:   stream,
   569  					History:  NewRange(5, 8),
   570  					Priority: Top,
   571  				},
   572  				Peer: node.ID(),
   573  			},
   574  		},
   575  	},
   576  		p2ptest.Exchange{
   577  			Label: "WantedHashes message",
   578  			Triggers: []p2ptest.Trigger{
   579  				{
   580  					Code: 1,
   581  					Msg: &OfferedHashesMsg{
   582  						HandoverProof: &HandoverProof{
   583  							Handover: &Handover{},
   584  						},
   585  						Hashes: hashes,
   586  						From:   5,
   587  						To:     8,
   588  						Stream: stream,
   589  					},
   590  					Peer: node.ID(),
   591  				},
   592  			},
   593  			Expects: []p2ptest.Expect{
   594  				{
   595  					Code: 2,
   596  					Msg: &WantedHashesMsg{
   597  						Stream: stream,
   598  						Want:   []byte{5},
   599  						From:   9,
   600  						To:     0,
   601  					},
   602  					Peer: node.ID(),
   603  				},
   604  			},
   605  		})
   606  	if err != nil {
   607  		t.Fatal(err)
   608  	}
   609  
   610  	if len(tc.receivedHashes) != 3 {
   611  		t.Fatalf("Expected number of received hashes %v, got %v", 3, len(tc.receivedHashes))
   612  	}
   613  
   614  	close(tc.wait0)
   615  
   616  	timeout := time.NewTimer(100 * time.Millisecond)
   617  	defer timeout.Stop()
   618  
   619  	select {
   620  	case <-tc.batchDone:
   621  		t.Fatal("batch done early")
   622  	case <-timeout.C:
   623  	}
   624  
   625  	close(tc.wait2)
   626  
   627  	timeout2 := time.NewTimer(10000 * time.Millisecond)
   628  	defer timeout2.Stop()
   629  
   630  	select {
   631  	case <-tc.batchDone:
   632  	case <-timeout2.C:
   633  		t.Fatal("timeout waiting batchdone call")
   634  	}
   635  
   636  }
   637  
   638  func TestStreamerRequestSubscriptionQuitMsgExchange(t *testing.T) {
   639  	tester, streamer, _, teardown, err := newStreamerTester(t, nil)
   640  	defer teardown()
   641  	if err != nil {
   642  		t.Fatal(err)
   643  	}
   644  
   645  	streamer.RegisterServerFunc("foo", func(p *Peer, t string, live bool) (Server, error) {
   646  		return newTestServer(t, 10), nil
   647  	})
   648  
   649  	node := tester.Nodes[0]
   650  
   651  	stream := NewStream("foo", "", true)
   652  	err = streamer.RequestSubscription(node.ID(), stream, NewRange(5, 8), Top)
   653  	if err != nil {
   654  		t.Fatalf("Expected no error, got %v", err)
   655  	}
   656  
   657  	err = tester.TestExchanges(
   658  		p2ptest.Exchange{
   659  			Label: "RequestSubscription message",
   660  			Expects: []p2ptest.Expect{
   661  				{
   662  					Code: 8,
   663  					Msg: &RequestSubscriptionMsg{
   664  						Stream:   stream,
   665  						History:  NewRange(5, 8),
   666  						Priority: Top,
   667  					},
   668  					Peer: node.ID(),
   669  				},
   670  			},
   671  		},
   672  		p2ptest.Exchange{
   673  			Label: "Subscribe message",
   674  			Triggers: []p2ptest.Trigger{
   675  				{
   676  					Code: 4,
   677  					Msg: &SubscribeMsg{
   678  						Stream:   stream,
   679  						History:  NewRange(5, 8),
   680  						Priority: Top,
   681  					},
   682  					Peer: node.ID(),
   683  				},
   684  			},
   685  			Expects: []p2ptest.Expect{
   686  				{
   687  					Code: 1,
   688  					Msg: &OfferedHashesMsg{
   689  						Stream: NewStream("foo", "", false),
   690  						HandoverProof: &HandoverProof{
   691  							Handover: &Handover{},
   692  						},
   693  						Hashes: make([]byte, HashSize),
   694  						From:   6,
   695  						To:     9,
   696  					},
   697  					Peer: node.ID(),
   698  				},
   699  				{
   700  					Code: 1,
   701  					Msg: &OfferedHashesMsg{
   702  						Stream: stream,
   703  						HandoverProof: &HandoverProof{
   704  							Handover: &Handover{},
   705  						},
   706  						From:   11,
   707  						To:     0,
   708  						Hashes: make([]byte, HashSize),
   709  					},
   710  					Peer: node.ID(),
   711  				},
   712  			},
   713  		},
   714  	)
   715  	if err != nil {
   716  		t.Fatal(err)
   717  	}
   718  
   719  	err = streamer.Quit(node.ID(), stream)
   720  	if err != nil {
   721  		t.Fatalf("Expected no error, got %v", err)
   722  	}
   723  
   724  	err = tester.TestExchanges(p2ptest.Exchange{
   725  		Label: "Quit message",
   726  		Expects: []p2ptest.Expect{
   727  			{
   728  				Code: 9,
   729  				Msg: &QuitMsg{
   730  					Stream: stream,
   731  				},
   732  				Peer: node.ID(),
   733  			},
   734  		},
   735  	})
   736  
   737  	if err != nil {
   738  		t.Fatal(err)
   739  	}
   740  
   741  	historyStream := getHistoryStream(stream)
   742  
   743  	err = streamer.Quit(node.ID(), historyStream)
   744  	if err != nil {
   745  		t.Fatalf("Expected no error, got %v", err)
   746  	}
   747  
   748  	err = tester.TestExchanges(p2ptest.Exchange{
   749  		Label: "Quit message",
   750  		Expects: []p2ptest.Expect{
   751  			{
   752  				Code: 9,
   753  				Msg: &QuitMsg{
   754  					Stream: historyStream,
   755  				},
   756  				Peer: node.ID(),
   757  			},
   758  		},
   759  	})
   760  
   761  	if err != nil {
   762  		t.Fatal(err)
   763  	}
   764  }
   765  
   766  // TestMaxPeerServersWithUnsubscribe creates a registry with a limited
   767  // number of stream servers, and performs a test with subscriptions and
   768  // unsubscriptions, checking if unsubscriptions will remove streams,
   769  // leaving place for new streams.
   770  func TestMaxPeerServersWithUnsubscribe(t *testing.T) {
   771  	var maxPeerServers = 6
   772  	tester, streamer, _, teardown, err := newStreamerTester(t, &RegistryOptions{
   773  		Retrieval:      RetrievalDisabled,
   774  		Syncing:        SyncingDisabled,
   775  		MaxPeerServers: maxPeerServers,
   776  	})
   777  	defer teardown()
   778  	if err != nil {
   779  		t.Fatal(err)
   780  	}
   781  
   782  	streamer.RegisterServerFunc("foo", func(p *Peer, t string, live bool) (Server, error) {
   783  		return newTestServer(t, 0), nil
   784  	})
   785  
   786  	node := tester.Nodes[0]
   787  
   788  	for i := 0; i < maxPeerServers+10; i++ {
   789  		stream := NewStream("foo", strconv.Itoa(i), true)
   790  
   791  		err = tester.TestExchanges(p2ptest.Exchange{
   792  			Label: "Subscribe message",
   793  			Triggers: []p2ptest.Trigger{
   794  				{
   795  					Code: 4,
   796  					Msg: &SubscribeMsg{
   797  						Stream:   stream,
   798  						Priority: Top,
   799  					},
   800  					Peer: node.ID(),
   801  				},
   802  			},
   803  			Expects: []p2ptest.Expect{
   804  				{
   805  					Code: 1,
   806  					Msg: &OfferedHashesMsg{
   807  						Stream: stream,
   808  						HandoverProof: &HandoverProof{
   809  							Handover: &Handover{},
   810  						},
   811  						Hashes: make([]byte, HashSize),
   812  						From:   1,
   813  						To:     0,
   814  					},
   815  					Peer: node.ID(),
   816  				},
   817  			},
   818  		})
   819  
   820  		if err != nil {
   821  			t.Fatal(err)
   822  		}
   823  
   824  		err = tester.TestExchanges(p2ptest.Exchange{
   825  			Label: "unsubscribe message",
   826  			Triggers: []p2ptest.Trigger{
   827  				{
   828  					Code: 0,
   829  					Msg: &UnsubscribeMsg{
   830  						Stream: stream,
   831  					},
   832  					Peer: node.ID(),
   833  				},
   834  			},
   835  		})
   836  
   837  		if err != nil {
   838  			t.Fatal(err)
   839  		}
   840  	}
   841  }
   842  
   843  // TestMaxPeerServersWithoutUnsubscribe creates a registry with a limited
   844  // number of stream servers, and performs subscriptions to detect subscriptions
   845  // error message exchange.
   846  func TestMaxPeerServersWithoutUnsubscribe(t *testing.T) {
   847  	var maxPeerServers = 6
   848  	tester, streamer, _, teardown, err := newStreamerTester(t, &RegistryOptions{
   849  		MaxPeerServers: maxPeerServers,
   850  	})
   851  	defer teardown()
   852  	if err != nil {
   853  		t.Fatal(err)
   854  	}
   855  
   856  	streamer.RegisterServerFunc("foo", func(p *Peer, t string, live bool) (Server, error) {
   857  		return newTestServer(t, 0), nil
   858  	})
   859  
   860  	node := tester.Nodes[0]
   861  
   862  	for i := 0; i < maxPeerServers+10; i++ {
   863  		stream := NewStream("foo", strconv.Itoa(i), true)
   864  
   865  		if i >= maxPeerServers {
   866  			err = tester.TestExchanges(p2ptest.Exchange{
   867  				Label: "Subscribe message",
   868  				Triggers: []p2ptest.Trigger{
   869  					{
   870  						Code: 4,
   871  						Msg: &SubscribeMsg{
   872  							Stream:   stream,
   873  							Priority: Top,
   874  						},
   875  						Peer: node.ID(),
   876  					},
   877  				},
   878  				Expects: []p2ptest.Expect{
   879  					{
   880  						Code: 7,
   881  						Msg: &SubscribeErrorMsg{
   882  							Error: ErrMaxPeerServers.Error(),
   883  						},
   884  						Peer: node.ID(),
   885  					},
   886  				},
   887  			})
   888  
   889  			if err != nil {
   890  				t.Fatal(err)
   891  			}
   892  			continue
   893  		}
   894  
   895  		err = tester.TestExchanges(p2ptest.Exchange{
   896  			Label: "Subscribe message",
   897  			Triggers: []p2ptest.Trigger{
   898  				{
   899  					Code: 4,
   900  					Msg: &SubscribeMsg{
   901  						Stream:   stream,
   902  						Priority: Top,
   903  					},
   904  					Peer: node.ID(),
   905  				},
   906  			},
   907  			Expects: []p2ptest.Expect{
   908  				{
   909  					Code: 1,
   910  					Msg: &OfferedHashesMsg{
   911  						Stream: stream,
   912  						HandoverProof: &HandoverProof{
   913  							Handover: &Handover{},
   914  						},
   915  						Hashes: make([]byte, HashSize),
   916  						From:   1,
   917  						To:     0,
   918  					},
   919  					Peer: node.ID(),
   920  				},
   921  			},
   922  		})
   923  
   924  		if err != nil {
   925  			t.Fatal(err)
   926  		}
   927  	}
   928  }
   929  
   930  //TestHasPriceImplementation is to check that the Registry has a
   931  //`Price` interface implementation
   932  func TestHasPriceImplementation(t *testing.T) {
   933  	_, r, _, teardown, err := newStreamerTester(t, &RegistryOptions{
   934  		Retrieval: RetrievalDisabled,
   935  		Syncing:   SyncingDisabled,
   936  	})
   937  	defer teardown()
   938  	if err != nil {
   939  		t.Fatal(err)
   940  	}
   941  
   942  	if r.prices == nil {
   943  		t.Fatal("No prices implementation available for the stream protocol")
   944  	}
   945  
   946  	pricesInstance, ok := r.prices.(*StreamerPrices)
   947  	if !ok {
   948  		t.Fatal("`Registry` does not have the expected Prices instance")
   949  	}
   950  	price := pricesInstance.Price(&ChunkDeliveryMsgRetrieval{})
   951  	if price == nil || price.Value == 0 || price.Value != pricesInstance.getChunkDeliveryMsgRetrievalPrice() {
   952  		t.Fatal("No prices set for chunk delivery msg")
   953  	}
   954  
   955  	price = pricesInstance.Price(&RetrieveRequestMsg{})
   956  	if price == nil || price.Value == 0 || price.Value != pricesInstance.getRetrieveRequestMsgPrice() {
   957  		t.Fatal("No prices set for chunk delivery msg")
   958  	}
   959  }
   960  
   961  /*
   962  TestRequestPeerSubscriptions is a unit test for stream's pull sync subscriptions.
   963  
   964  The test does:
   965  	* assign each connected peer to a bin map
   966    * build up a known kademlia in advance
   967  	* run the EachConn function, which returns supposed subscription bins
   968  	* store all supposed bins per peer in a map
   969  	* check that all peers have the expected subscriptions
   970  
   971  This kad table and its peers are copied from network.TestKademliaCase1,
   972  it represents an edge case but for the purpose of testing the
   973  syncing subscriptions it is just fine.
   974  
   975  Addresses used in this test are discovered as part of the simulation network
   976  in higher level tests for streaming. They were generated randomly.
   977  
   978  The resulting kademlia looks like this:
   979  =========================================================================
   980  Fri Dec 21 20:02:39 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 7efef1
   981  population: 12 (12), MinProxBinSize: 2, MinBinSize: 2, MaxBinSize: 4
   982  000  2 8196 835f                    |  2 8196 (0) 835f (0)
   983  001  2 2690 28f0                    |  2 2690 (0) 28f0 (0)
   984  002  2 4d72 4a45                    |  2 4d72 (0) 4a45 (0)
   985  003  1 646e                         |  1 646e (0)
   986  004  3 769c 76d1 7656               |  3 769c (0) 76d1 (0) 7656 (0)
   987  ============ DEPTH: 5 ==========================================
   988  005  1 7a48                         |  1 7a48 (0)
   989  006  1 7cbd                         |  1 7cbd (0)
   990  007  0                              |  0
   991  008  0                              |  0
   992  009  0                              |  0
   993  010  0                              |  0
   994  011  0                              |  0
   995  012  0                              |  0
   996  013  0                              |  0
   997  014  0                              |  0
   998  015  0                              |  0
   999  =========================================================================
  1000  */
  1001  func TestRequestPeerSubscriptions(t *testing.T) {
  1002  	// the pivot address; this is the actual kademlia node
  1003  	pivotAddr := "7efef1c41d77f843ad167be95f6660567eb8a4a59f39240000cce2e0d65baf8e"
  1004  
  1005  	// a map of bin number to addresses from the given kademlia
  1006  	binMap := make(map[int][]string)
  1007  	binMap[0] = []string{
  1008  		"835fbbf1d16ba7347b6e2fc552d6e982148d29c624ea20383850df3c810fa8fc",
  1009  		"81968a2d8fb39114342ee1da85254ec51e0608d7f0f6997c2a8354c260a71009",
  1010  	}
  1011  	binMap[1] = []string{
  1012  		"28f0bc1b44658548d6e05dd16d4c2fe77f1da5d48b6774bc4263b045725d0c19",
  1013  		"2690a910c33ee37b91eb6c4e0731d1d345e2dc3b46d308503a6e85bbc242c69e",
  1014  	}
  1015  	binMap[2] = []string{
  1016  		"4a45f1fc63e1a9cb9dfa44c98da2f3d20c2923e5d75ff60b2db9d1bdb0c54d51",
  1017  		"4d72a04ddeb851a68cd197ef9a92a3e2ff01fbbff638e64929dd1a9c2e150112",
  1018  	}
  1019  	binMap[3] = []string{
  1020  		"646e9540c84f6a2f9cf6585d45a4c219573b4fd1b64a3c9a1386fc5cf98c0d4d",
  1021  	}
  1022  	binMap[4] = []string{
  1023  		"7656caccdc79cd8d7ce66d415cc96a718e8271c62fb35746bfc2b49faf3eebf3",
  1024  		"76d1e83c71ca246d042e37ff1db181f2776265fbcfdc890ce230bfa617c9c2f0",
  1025  		"769ce86aa90b518b7ed382f9fdacfbed93574e18dc98fe6c342e4f9f409c2d5a",
  1026  	}
  1027  	binMap[5] = []string{
  1028  		"7a48f75f8ca60487ae42d6f92b785581b40b91f2da551ae73d5eae46640e02e8",
  1029  	}
  1030  	binMap[6] = []string{
  1031  		"7cbd42350bde8e18ae5b955b5450f8e2cef3419f92fbf5598160c60fd78619f0",
  1032  	}
  1033  
  1034  	// create the pivot's kademlia
  1035  	addr := common.FromHex(pivotAddr)
  1036  	k := network.NewKademlia(addr, network.NewKadParams())
  1037  
  1038  	// construct the peers and the kademlia
  1039  	for _, binaddrs := range binMap {
  1040  		for _, a := range binaddrs {
  1041  			addr := common.FromHex(a)
  1042  			k.On(network.NewPeer(&network.BzzPeer{BzzAddr: &network.BzzAddr{OAddr: addr}}, k))
  1043  		}
  1044  	}
  1045  
  1046  	// TODO: check kad table is same
  1047  	// currently k.String() prints date so it will never be the same :)
  1048  	// --> implement JSON representation of kad table
  1049  	log.Debug(k.String())
  1050  
  1051  	// simulate that we would do subscriptions: just store the bin numbers
  1052  	fakeSubscriptions := make(map[string][]int)
  1053  	//after the test, we need to reset the subscriptionFunc to the default
  1054  	defer func() { subscriptionFunc = doRequestSubscription }()
  1055  	// define the function which should run for each connection
  1056  	// instead of doing real subscriptions, we just store the bin numbers
  1057  	subscriptionFunc = func(r *Registry, p *network.Peer, bin uint8, subs map[enode.ID]map[Stream]struct{}) bool {
  1058  		// get the peer ID
  1059  		peerstr := fmt.Sprintf("%x", p.Over())
  1060  		// create the array of bins per peer
  1061  		if _, ok := fakeSubscriptions[peerstr]; !ok {
  1062  			fakeSubscriptions[peerstr] = make([]int, 0)
  1063  		}
  1064  		// store the (fake) bin subscription
  1065  		log.Debug(fmt.Sprintf("Adding fake subscription for peer %s with bin %d", peerstr, bin))
  1066  		fakeSubscriptions[peerstr] = append(fakeSubscriptions[peerstr], int(bin))
  1067  		return true
  1068  	}
  1069  	// create just a simple Registry object in order to be able to call...
  1070  	r := &Registry{}
  1071  	r.requestPeerSubscriptions(k, nil)
  1072  	// calculate the kademlia depth
  1073  	kdepth := k.NeighbourhoodDepth()
  1074  
  1075  	// now, check that all peers have the expected (fake) subscriptions
  1076  	// iterate the bin map
  1077  	for bin, peers := range binMap {
  1078  		// for every peer...
  1079  		for _, peer := range peers {
  1080  			// ...get its (fake) subscriptions
  1081  			fakeSubsForPeer := fakeSubscriptions[peer]
  1082  			// if the peer's bin is shallower than the kademlia depth...
  1083  			if bin < kdepth {
  1084  				// (iterate all (fake) subscriptions)
  1085  				for _, subbin := range fakeSubsForPeer {
  1086  					// ...only the peer's bin should be "subscribed"
  1087  					// (and thus have only one subscription)
  1088  					if subbin != bin || len(fakeSubsForPeer) != 1 {
  1089  						t.Fatalf("Did not get expected subscription for bin < depth; bin of peer %s: %d, subscription: %d", peer, bin, subbin)
  1090  					}
  1091  				}
  1092  			} else { //if the peer's bin is equal or higher than the kademlia depth...
  1093  				// (iterate all (fake) subscriptions)
  1094  				for i, subbin := range fakeSubsForPeer {
  1095  					// ...each bin from the peer's bin number up to k.MaxProxDisplay should be "subscribed"
  1096  					// as we start from depth we can use the iteration index to check
  1097  					if subbin != i+kdepth {
  1098  						t.Fatalf("Did not get expected subscription for bin > depth; bin of peer %s: %d, subscription: %d", peer, bin, subbin)
  1099  					}
  1100  					// the last "subscription" should be k.MaxProxDisplay
  1101  					if i == len(fakeSubsForPeer)-1 && subbin != k.MaxProxDisplay {
  1102  						t.Fatalf("Expected last subscription to be: %d, but is: %d", k.MaxProxDisplay, subbin)
  1103  					}
  1104  				}
  1105  			}
  1106  		}
  1107  	}
  1108  
  1109  	// print some output
  1110  	for p, subs := range fakeSubscriptions {
  1111  		log.Debug(fmt.Sprintf("Peer %s has the following fake subscriptions: ", p))
  1112  		for _, bin := range subs {
  1113  			log.Debug(fmt.Sprintf("%d,", bin))
  1114  		}
  1115  	}
  1116  }