github.com/pslzym/go-ethereum@v1.8.17-0.20180926104442-4b6824e07b1b/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  	"testing"
    24  	"time"
    25  
    26  	"github.com/ethereum/go-ethereum/crypto/sha3"
    27  	p2ptest "github.com/ethereum/go-ethereum/p2p/testing"
    28  )
    29  
    30  func TestStreamerSubscribe(t *testing.T) {
    31  	tester, streamer, _, teardown, err := newStreamerTester(t)
    32  	defer teardown()
    33  	if err != nil {
    34  		t.Fatal(err)
    35  	}
    36  
    37  	stream := NewStream("foo", "", true)
    38  	err = streamer.Subscribe(tester.Nodes[0].ID(), stream, NewRange(0, 0), Top)
    39  	if err == nil || err.Error() != "stream foo not registered" {
    40  		t.Fatalf("Expected error %v, got %v", "stream foo not registered", err)
    41  	}
    42  }
    43  
    44  func TestStreamerRequestSubscription(t *testing.T) {
    45  	tester, streamer, _, teardown, err := newStreamerTester(t)
    46  	defer teardown()
    47  	if err != nil {
    48  		t.Fatal(err)
    49  	}
    50  
    51  	stream := NewStream("foo", "", false)
    52  	err = streamer.RequestSubscription(tester.Nodes[0].ID(), stream, &Range{}, Top)
    53  	if err == nil || err.Error() != "stream foo not registered" {
    54  		t.Fatalf("Expected error %v, got %v", "stream foo not registered", err)
    55  	}
    56  }
    57  
    58  var (
    59  	hash0         = sha3.Sum256([]byte{0})
    60  	hash1         = sha3.Sum256([]byte{1})
    61  	hash2         = sha3.Sum256([]byte{2})
    62  	hashesTmp     = append(hash0[:], hash1[:]...)
    63  	hashes        = append(hashesTmp, hash2[:]...)
    64  	corruptHashes = append(hashes[:40])
    65  )
    66  
    67  type testClient struct {
    68  	t              string
    69  	wait0          chan bool
    70  	wait2          chan bool
    71  	batchDone      chan bool
    72  	receivedHashes map[string][]byte
    73  }
    74  
    75  func newTestClient(t string) *testClient {
    76  	return &testClient{
    77  		t:              t,
    78  		wait0:          make(chan bool),
    79  		wait2:          make(chan bool),
    80  		batchDone:      make(chan bool),
    81  		receivedHashes: make(map[string][]byte),
    82  	}
    83  }
    84  
    85  func (self *testClient) NeedData(ctx context.Context, hash []byte) func(context.Context) error {
    86  	self.receivedHashes[string(hash)] = hash
    87  	if bytes.Equal(hash, hash0[:]) {
    88  		return func(context.Context) error {
    89  			<-self.wait0
    90  			return nil
    91  		}
    92  	} else if bytes.Equal(hash, hash2[:]) {
    93  		return func(context.Context) error {
    94  			<-self.wait2
    95  			return nil
    96  		}
    97  	}
    98  	return nil
    99  }
   100  
   101  func (self *testClient) BatchDone(Stream, uint64, []byte, []byte) func() (*TakeoverProof, error) {
   102  	close(self.batchDone)
   103  	return nil
   104  }
   105  
   106  func (self *testClient) Close() {}
   107  
   108  type testServer struct {
   109  	t string
   110  }
   111  
   112  func newTestServer(t string) *testServer {
   113  	return &testServer{
   114  		t: t,
   115  	}
   116  }
   117  
   118  func (self *testServer) SetNextBatch(from uint64, to uint64) ([]byte, uint64, uint64, *HandoverProof, error) {
   119  	return make([]byte, HashSize), from + 1, to + 1, nil, nil
   120  }
   121  
   122  func (self *testServer) GetData(context.Context, []byte) ([]byte, error) {
   123  	return nil, nil
   124  }
   125  
   126  func (self *testServer) Close() {
   127  }
   128  
   129  func TestStreamerDownstreamSubscribeUnsubscribeMsgExchange(t *testing.T) {
   130  	tester, streamer, _, teardown, err := newStreamerTester(t)
   131  	defer teardown()
   132  	if err != nil {
   133  		t.Fatal(err)
   134  	}
   135  
   136  	streamer.RegisterClientFunc("foo", func(p *Peer, t string, live bool) (Client, error) {
   137  		return newTestClient(t), nil
   138  	})
   139  
   140  	node := tester.Nodes[0]
   141  
   142  	stream := NewStream("foo", "", true)
   143  	err = streamer.Subscribe(node.ID(), stream, NewRange(5, 8), Top)
   144  	if err != nil {
   145  		t.Fatalf("Expected no error, got %v", err)
   146  	}
   147  
   148  	err = tester.TestExchanges(
   149  		p2ptest.Exchange{
   150  			Label: "Subscribe message",
   151  			Expects: []p2ptest.Expect{
   152  				{
   153  					Code: 4,
   154  					Msg: &SubscribeMsg{
   155  						Stream:   stream,
   156  						History:  NewRange(5, 8),
   157  						Priority: Top,
   158  					},
   159  					Peer: node.ID(),
   160  				},
   161  			},
   162  		},
   163  		// trigger OfferedHashesMsg to actually create the client
   164  		p2ptest.Exchange{
   165  			Label: "OfferedHashes message",
   166  			Triggers: []p2ptest.Trigger{
   167  				{
   168  					Code: 1,
   169  					Msg: &OfferedHashesMsg{
   170  						HandoverProof: &HandoverProof{
   171  							Handover: &Handover{},
   172  						},
   173  						Hashes: hashes,
   174  						From:   5,
   175  						To:     8,
   176  						Stream: stream,
   177  					},
   178  					Peer: node.ID(),
   179  				},
   180  			},
   181  			Expects: []p2ptest.Expect{
   182  				{
   183  					Code: 2,
   184  					Msg: &WantedHashesMsg{
   185  						Stream: stream,
   186  						Want:   []byte{5},
   187  						From:   9,
   188  						To:     0,
   189  					},
   190  					Peer: node.ID(),
   191  				},
   192  			},
   193  		},
   194  	)
   195  	if err != nil {
   196  		t.Fatal(err)
   197  	}
   198  
   199  	err = streamer.Unsubscribe(node.ID(), stream)
   200  	if err != nil {
   201  		t.Fatalf("Expected no error, got %v", err)
   202  	}
   203  
   204  	err = tester.TestExchanges(p2ptest.Exchange{
   205  		Label: "Unsubscribe message",
   206  		Expects: []p2ptest.Expect{
   207  			{
   208  				Code: 0,
   209  				Msg: &UnsubscribeMsg{
   210  					Stream: stream,
   211  				},
   212  				Peer: node.ID(),
   213  			},
   214  		},
   215  	})
   216  
   217  	if err != nil {
   218  		t.Fatal(err)
   219  	}
   220  }
   221  
   222  func TestStreamerUpstreamSubscribeUnsubscribeMsgExchange(t *testing.T) {
   223  	tester, streamer, _, teardown, err := newStreamerTester(t)
   224  	defer teardown()
   225  	if err != nil {
   226  		t.Fatal(err)
   227  	}
   228  
   229  	stream := NewStream("foo", "", false)
   230  
   231  	streamer.RegisterServerFunc("foo", func(p *Peer, t string, live bool) (Server, error) {
   232  		return newTestServer(t), nil
   233  	})
   234  
   235  	node := tester.Nodes[0]
   236  
   237  	err = tester.TestExchanges(p2ptest.Exchange{
   238  		Label: "Subscribe message",
   239  		Triggers: []p2ptest.Trigger{
   240  			{
   241  				Code: 4,
   242  				Msg: &SubscribeMsg{
   243  					Stream:   stream,
   244  					History:  NewRange(5, 8),
   245  					Priority: Top,
   246  				},
   247  				Peer: node.ID(),
   248  			},
   249  		},
   250  		Expects: []p2ptest.Expect{
   251  			{
   252  				Code: 1,
   253  				Msg: &OfferedHashesMsg{
   254  					Stream: stream,
   255  					HandoverProof: &HandoverProof{
   256  						Handover: &Handover{},
   257  					},
   258  					Hashes: make([]byte, HashSize),
   259  					From:   6,
   260  					To:     9,
   261  				},
   262  				Peer: node.ID(),
   263  			},
   264  		},
   265  	})
   266  
   267  	if err != nil {
   268  		t.Fatal(err)
   269  	}
   270  
   271  	err = tester.TestExchanges(p2ptest.Exchange{
   272  		Label: "unsubscribe message",
   273  		Triggers: []p2ptest.Trigger{
   274  			{
   275  				Code: 0,
   276  				Msg: &UnsubscribeMsg{
   277  					Stream: stream,
   278  				},
   279  				Peer: node.ID(),
   280  			},
   281  		},
   282  	})
   283  
   284  	if err != nil {
   285  		t.Fatal(err)
   286  	}
   287  }
   288  
   289  func TestStreamerUpstreamSubscribeUnsubscribeMsgExchangeLive(t *testing.T) {
   290  	tester, streamer, _, teardown, err := newStreamerTester(t)
   291  	defer teardown()
   292  	if err != nil {
   293  		t.Fatal(err)
   294  	}
   295  
   296  	stream := NewStream("foo", "", true)
   297  
   298  	streamer.RegisterServerFunc("foo", func(p *Peer, t string, live bool) (Server, error) {
   299  		return newTestServer(t), nil
   300  	})
   301  
   302  	node := tester.Nodes[0]
   303  
   304  	err = tester.TestExchanges(p2ptest.Exchange{
   305  		Label: "Subscribe message",
   306  		Triggers: []p2ptest.Trigger{
   307  			{
   308  				Code: 4,
   309  				Msg: &SubscribeMsg{
   310  					Stream:   stream,
   311  					Priority: Top,
   312  				},
   313  				Peer: node.ID(),
   314  			},
   315  		},
   316  		Expects: []p2ptest.Expect{
   317  			{
   318  				Code: 1,
   319  				Msg: &OfferedHashesMsg{
   320  					Stream: stream,
   321  					HandoverProof: &HandoverProof{
   322  						Handover: &Handover{},
   323  					},
   324  					Hashes: make([]byte, HashSize),
   325  					From:   1,
   326  					To:     1,
   327  				},
   328  				Peer: node.ID(),
   329  			},
   330  		},
   331  	})
   332  
   333  	if err != nil {
   334  		t.Fatal(err)
   335  	}
   336  
   337  	err = tester.TestExchanges(p2ptest.Exchange{
   338  		Label: "unsubscribe message",
   339  		Triggers: []p2ptest.Trigger{
   340  			{
   341  				Code: 0,
   342  				Msg: &UnsubscribeMsg{
   343  					Stream: stream,
   344  				},
   345  				Peer: node.ID(),
   346  			},
   347  		},
   348  	})
   349  
   350  	if err != nil {
   351  		t.Fatal(err)
   352  	}
   353  }
   354  
   355  func TestStreamerUpstreamSubscribeErrorMsgExchange(t *testing.T) {
   356  	tester, streamer, _, teardown, err := newStreamerTester(t)
   357  	defer teardown()
   358  	if err != nil {
   359  		t.Fatal(err)
   360  	}
   361  
   362  	streamer.RegisterServerFunc("foo", func(p *Peer, t string, live bool) (Server, error) {
   363  		return newTestServer(t), nil
   364  	})
   365  
   366  	stream := NewStream("bar", "", true)
   367  
   368  	node := tester.Nodes[0]
   369  
   370  	err = tester.TestExchanges(p2ptest.Exchange{
   371  		Label: "Subscribe message",
   372  		Triggers: []p2ptest.Trigger{
   373  			{
   374  				Code: 4,
   375  				Msg: &SubscribeMsg{
   376  					Stream:   stream,
   377  					History:  NewRange(5, 8),
   378  					Priority: Top,
   379  				},
   380  				Peer: node.ID(),
   381  			},
   382  		},
   383  		Expects: []p2ptest.Expect{
   384  			{
   385  				Code: 7,
   386  				Msg: &SubscribeErrorMsg{
   387  					Error: "stream bar not registered",
   388  				},
   389  				Peer: node.ID(),
   390  			},
   391  		},
   392  	})
   393  
   394  	if err != nil {
   395  		t.Fatal(err)
   396  	}
   397  }
   398  
   399  func TestStreamerUpstreamSubscribeLiveAndHistory(t *testing.T) {
   400  	tester, streamer, _, teardown, err := newStreamerTester(t)
   401  	defer teardown()
   402  	if err != nil {
   403  		t.Fatal(err)
   404  	}
   405  
   406  	stream := NewStream("foo", "", true)
   407  
   408  	streamer.RegisterServerFunc("foo", func(p *Peer, t string, live bool) (Server, error) {
   409  		return &testServer{
   410  			t: t,
   411  		}, nil
   412  	})
   413  
   414  	node := tester.Nodes[0]
   415  
   416  	err = tester.TestExchanges(p2ptest.Exchange{
   417  		Label: "Subscribe message",
   418  		Triggers: []p2ptest.Trigger{
   419  			{
   420  				Code: 4,
   421  				Msg: &SubscribeMsg{
   422  					Stream:   stream,
   423  					History:  NewRange(5, 8),
   424  					Priority: Top,
   425  				},
   426  				Peer: node.ID(),
   427  			},
   428  		},
   429  		Expects: []p2ptest.Expect{
   430  			{
   431  				Code: 1,
   432  				Msg: &OfferedHashesMsg{
   433  					Stream: NewStream("foo", "", false),
   434  					HandoverProof: &HandoverProof{
   435  						Handover: &Handover{},
   436  					},
   437  					Hashes: make([]byte, HashSize),
   438  					From:   6,
   439  					To:     9,
   440  				},
   441  				Peer: node.ID(),
   442  			},
   443  			{
   444  				Code: 1,
   445  				Msg: &OfferedHashesMsg{
   446  					Stream: stream,
   447  					HandoverProof: &HandoverProof{
   448  						Handover: &Handover{},
   449  					},
   450  					From:   1,
   451  					To:     1,
   452  					Hashes: make([]byte, HashSize),
   453  				},
   454  				Peer: node.ID(),
   455  			},
   456  		},
   457  	})
   458  
   459  	if err != nil {
   460  		t.Fatal(err)
   461  	}
   462  }
   463  
   464  func TestStreamerDownstreamCorruptHashesMsgExchange(t *testing.T) {
   465  	tester, streamer, _, teardown, err := newStreamerTester(t)
   466  	defer teardown()
   467  	if err != nil {
   468  		t.Fatal(err)
   469  	}
   470  
   471  	stream := NewStream("foo", "", true)
   472  
   473  	var tc *testClient
   474  
   475  	streamer.RegisterClientFunc("foo", func(p *Peer, t string, live bool) (Client, error) {
   476  		tc = newTestClient(t)
   477  		return tc, nil
   478  	})
   479  
   480  	peerID := tester.IDs[0]
   481  
   482  	err = streamer.Subscribe(peerID, stream, NewRange(5, 8), Top)
   483  	if err != nil {
   484  		t.Fatalf("Expected no error, got %v", err)
   485  	}
   486  
   487  	err = tester.TestExchanges(p2ptest.Exchange{
   488  		Label: "Subscribe message",
   489  		Expects: []p2ptest.Expect{
   490  			{
   491  				Code: 4,
   492  				Msg: &SubscribeMsg{
   493  					Stream:   stream,
   494  					History:  NewRange(5, 8),
   495  					Priority: Top,
   496  				},
   497  				Peer: peerID,
   498  			},
   499  		},
   500  	},
   501  		p2ptest.Exchange{
   502  			Label: "Corrupt offered hash message",
   503  			Triggers: []p2ptest.Trigger{
   504  				{
   505  					Code: 1,
   506  					Msg: &OfferedHashesMsg{
   507  						HandoverProof: &HandoverProof{
   508  							Handover: &Handover{},
   509  						},
   510  						Hashes: corruptHashes,
   511  						From:   5,
   512  						To:     8,
   513  						Stream: stream,
   514  					},
   515  					Peer: peerID,
   516  				},
   517  			},
   518  		})
   519  	if err != nil {
   520  		t.Fatal(err)
   521  	}
   522  
   523  	expectedError := errors.New("Message handler error: (msg code 1): error invalid hashes length (len: 40)")
   524  	if err := tester.TestDisconnected(&p2ptest.Disconnect{Peer: tester.IDs[0], Error: expectedError}); err != nil {
   525  		t.Fatal(err)
   526  	}
   527  }
   528  
   529  func TestStreamerDownstreamOfferedHashesMsgExchange(t *testing.T) {
   530  	tester, streamer, _, teardown, err := newStreamerTester(t)
   531  	defer teardown()
   532  	if err != nil {
   533  		t.Fatal(err)
   534  	}
   535  
   536  	stream := NewStream("foo", "", true)
   537  
   538  	var tc *testClient
   539  
   540  	streamer.RegisterClientFunc("foo", func(p *Peer, t string, live bool) (Client, error) {
   541  		tc = newTestClient(t)
   542  		return tc, nil
   543  	})
   544  
   545  	node := tester.Nodes[0]
   546  
   547  	err = streamer.Subscribe(node.ID(), stream, NewRange(5, 8), Top)
   548  	if err != nil {
   549  		t.Fatalf("Expected no error, got %v", err)
   550  	}
   551  
   552  	err = tester.TestExchanges(p2ptest.Exchange{
   553  		Label: "Subscribe message",
   554  		Expects: []p2ptest.Expect{
   555  			{
   556  				Code: 4,
   557  				Msg: &SubscribeMsg{
   558  					Stream:   stream,
   559  					History:  NewRange(5, 8),
   560  					Priority: Top,
   561  				},
   562  				Peer: node.ID(),
   563  			},
   564  		},
   565  	},
   566  		p2ptest.Exchange{
   567  			Label: "WantedHashes message",
   568  			Triggers: []p2ptest.Trigger{
   569  				{
   570  					Code: 1,
   571  					Msg: &OfferedHashesMsg{
   572  						HandoverProof: &HandoverProof{
   573  							Handover: &Handover{},
   574  						},
   575  						Hashes: hashes,
   576  						From:   5,
   577  						To:     8,
   578  						Stream: stream,
   579  					},
   580  					Peer: node.ID(),
   581  				},
   582  			},
   583  			Expects: []p2ptest.Expect{
   584  				{
   585  					Code: 2,
   586  					Msg: &WantedHashesMsg{
   587  						Stream: stream,
   588  						Want:   []byte{5},
   589  						From:   9,
   590  						To:     0,
   591  					},
   592  					Peer: node.ID(),
   593  				},
   594  			},
   595  		})
   596  	if err != nil {
   597  		t.Fatal(err)
   598  	}
   599  
   600  	if len(tc.receivedHashes) != 3 {
   601  		t.Fatalf("Expected number of received hashes %v, got %v", 3, len(tc.receivedHashes))
   602  	}
   603  
   604  	close(tc.wait0)
   605  
   606  	timeout := time.NewTimer(100 * time.Millisecond)
   607  	defer timeout.Stop()
   608  
   609  	select {
   610  	case <-tc.batchDone:
   611  		t.Fatal("batch done early")
   612  	case <-timeout.C:
   613  	}
   614  
   615  	close(tc.wait2)
   616  
   617  	timeout2 := time.NewTimer(10000 * time.Millisecond)
   618  	defer timeout2.Stop()
   619  
   620  	select {
   621  	case <-tc.batchDone:
   622  	case <-timeout2.C:
   623  		t.Fatal("timeout waiting batchdone call")
   624  	}
   625  
   626  }
   627  
   628  func TestStreamerRequestSubscriptionQuitMsgExchange(t *testing.T) {
   629  	tester, streamer, _, teardown, err := newStreamerTester(t)
   630  	defer teardown()
   631  	if err != nil {
   632  		t.Fatal(err)
   633  	}
   634  
   635  	streamer.RegisterServerFunc("foo", func(p *Peer, t string, live bool) (Server, error) {
   636  		return newTestServer(t), nil
   637  	})
   638  
   639  	node := tester.Nodes[0]
   640  
   641  	stream := NewStream("foo", "", true)
   642  	err = streamer.RequestSubscription(node.ID(), stream, NewRange(5, 8), Top)
   643  	if err != nil {
   644  		t.Fatalf("Expected no error, got %v", err)
   645  	}
   646  
   647  	err = tester.TestExchanges(
   648  		p2ptest.Exchange{
   649  			Label: "RequestSubscription message",
   650  			Expects: []p2ptest.Expect{
   651  				{
   652  					Code: 8,
   653  					Msg: &RequestSubscriptionMsg{
   654  						Stream:   stream,
   655  						History:  NewRange(5, 8),
   656  						Priority: Top,
   657  					},
   658  					Peer: node.ID(),
   659  				},
   660  			},
   661  		},
   662  		p2ptest.Exchange{
   663  			Label: "Subscribe message",
   664  			Triggers: []p2ptest.Trigger{
   665  				{
   666  					Code: 4,
   667  					Msg: &SubscribeMsg{
   668  						Stream:   stream,
   669  						History:  NewRange(5, 8),
   670  						Priority: Top,
   671  					},
   672  					Peer: node.ID(),
   673  				},
   674  			},
   675  			Expects: []p2ptest.Expect{
   676  				{
   677  					Code: 1,
   678  					Msg: &OfferedHashesMsg{
   679  						Stream: NewStream("foo", "", false),
   680  						HandoverProof: &HandoverProof{
   681  							Handover: &Handover{},
   682  						},
   683  						Hashes: make([]byte, HashSize),
   684  						From:   6,
   685  						To:     9,
   686  					},
   687  					Peer: node.ID(),
   688  				},
   689  				{
   690  					Code: 1,
   691  					Msg: &OfferedHashesMsg{
   692  						Stream: stream,
   693  						HandoverProof: &HandoverProof{
   694  							Handover: &Handover{},
   695  						},
   696  						From:   1,
   697  						To:     1,
   698  						Hashes: make([]byte, HashSize),
   699  					},
   700  					Peer: node.ID(),
   701  				},
   702  			},
   703  		},
   704  	)
   705  	if err != nil {
   706  		t.Fatal(err)
   707  	}
   708  
   709  	err = streamer.Quit(node.ID(), stream)
   710  	if err != nil {
   711  		t.Fatalf("Expected no error, got %v", err)
   712  	}
   713  
   714  	err = tester.TestExchanges(p2ptest.Exchange{
   715  		Label: "Quit message",
   716  		Expects: []p2ptest.Expect{
   717  			{
   718  				Code: 9,
   719  				Msg: &QuitMsg{
   720  					Stream: stream,
   721  				},
   722  				Peer: node.ID(),
   723  			},
   724  		},
   725  	})
   726  
   727  	if err != nil {
   728  		t.Fatal(err)
   729  	}
   730  
   731  	historyStream := getHistoryStream(stream)
   732  
   733  	err = streamer.Quit(node.ID(), historyStream)
   734  	if err != nil {
   735  		t.Fatalf("Expected no error, got %v", err)
   736  	}
   737  
   738  	err = tester.TestExchanges(p2ptest.Exchange{
   739  		Label: "Quit message",
   740  		Expects: []p2ptest.Expect{
   741  			{
   742  				Code: 9,
   743  				Msg: &QuitMsg{
   744  					Stream: historyStream,
   745  				},
   746  				Peer: node.ID(),
   747  			},
   748  		},
   749  	})
   750  
   751  	if err != nil {
   752  		t.Fatal(err)
   753  	}
   754  }