github.com/xinfinOrg/xdposchain@v1.1.0/p2p/dial_test.go (about)

     1  // Copyright 2015 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 p2p
    18  
    19  import (
    20  	"encoding/binary"
    21  	"net"
    22  	"reflect"
    23  	"testing"
    24  	"time"
    25  
    26  	"github.com/davecgh/go-spew/spew"
    27  	"github.com/ethereum/go-ethereum/p2p/enode"
    28  	"github.com/ethereum/go-ethereum/p2p/enr"
    29  	"github.com/ethereum/go-ethereum/p2p/netutil"
    30  )
    31  
    32  func init() {
    33  	spew.Config.Indent = "\t"
    34  }
    35  
    36  type dialtest struct {
    37  	init   *dialstate // state before and after the test.
    38  	rounds []round
    39  }
    40  
    41  type round struct {
    42  	peers []*Peer // current peer set
    43  	done  []task  // tasks that got done this round
    44  	new   []task  // the result must match this one
    45  }
    46  
    47  func runDialTest(t *testing.T, test dialtest) {
    48  	var (
    49  		vtime   time.Time
    50  		running int
    51  	)
    52  	pm := func(ps []*Peer) map[enode.ID]*Peer {
    53  		m := make(map[enode.ID]*Peer)
    54  		for _, p := range ps {
    55  			m[p.ID()] = p
    56  		}
    57  		return m
    58  	}
    59  	for i, round := range test.rounds {
    60  		for _, task := range round.done {
    61  			running--
    62  			if running < 0 {
    63  				panic("running task counter underflow")
    64  			}
    65  			test.init.taskDone(task, vtime)
    66  		}
    67  
    68  		new := test.init.newTasks(running, pm(round.peers), vtime)
    69  		if !sametasks(new, round.new) {
    70  			t.Errorf("round %d: new tasks mismatch:\ngot %v\nwant %v\nstate: %v\nrunning: %v\n",
    71  				i, spew.Sdump(new), spew.Sdump(round.new), spew.Sdump(test.init), spew.Sdump(running))
    72  		}
    73  		t.Log("tasks:", spew.Sdump(new))
    74  
    75  		// Time advances by 16 seconds on every round.
    76  		vtime = vtime.Add(16 * time.Second)
    77  		running += len(new)
    78  	}
    79  }
    80  
    81  type fakeTable []*enode.Node
    82  
    83  func (t fakeTable) Self() *enode.Node                     { return new(enode.Node) }
    84  func (t fakeTable) Close()                                {}
    85  func (t fakeTable) LookupRandom() []*enode.Node           { return nil }
    86  func (t fakeTable) Resolve(*enode.Node) *enode.Node       { return nil }
    87  func (t fakeTable) ReadRandomNodes(buf []*enode.Node) int { return copy(buf, t) }
    88  
    89  // This test checks that dynamic dials are launched from discovery results.
    90  func TestDialStateDynDial(t *testing.T) {
    91  	runDialTest(t, dialtest{
    92  		init: newDialState(enode.ID{}, nil, nil, fakeTable{}, 5, nil),
    93  		rounds: []round{
    94  			// A discovery query is launched.
    95  			{
    96  				peers: []*Peer{
    97  					{rw: &conn{flags: staticDialedConn, node: newNode(uintID(0), nil)}},
    98  					{rw: &conn{flags: dynDialedConn, node: newNode(uintID(1), nil)}},
    99  					{rw: &conn{flags: dynDialedConn, node: newNode(uintID(2), nil)}},
   100  				},
   101  				new: []task{&discoverTask{}},
   102  			},
   103  			// Dynamic dials are launched when it completes.
   104  			{
   105  				peers: []*Peer{
   106  					{rw: &conn{flags: staticDialedConn, node: newNode(uintID(0), nil)}},
   107  					{rw: &conn{flags: dynDialedConn, node: newNode(uintID(1), nil)}},
   108  					{rw: &conn{flags: dynDialedConn, node: newNode(uintID(2), nil)}},
   109  				},
   110  				done: []task{
   111  					&discoverTask{results: []*enode.Node{
   112  						newNode(uintID(2), nil), // this one is already connected and not dialed.
   113  						newNode(uintID(3), nil),
   114  						newNode(uintID(4), nil),
   115  						newNode(uintID(5), nil),
   116  						newNode(uintID(6), nil), // these are not tried because max dyn dials is 5
   117  						newNode(uintID(7), nil), // ...
   118  					}},
   119  				},
   120  				new: []task{
   121  					&dialTask{flags: dynDialedConn, dest: newNode(uintID(2), nil)},
   122  					&dialTask{flags: dynDialedConn, dest: newNode(uintID(3), nil)},
   123  					&dialTask{flags: dynDialedConn, dest: newNode(uintID(4), nil)},
   124  				},
   125  			},
   126  			// Some of the dials complete but no new ones are launched yet because
   127  			// the sum of active dial count and dynamic peer count is == maxDynDials.
   128  			{
   129  				peers: []*Peer{
   130  					{rw: &conn{flags: staticDialedConn, node: newNode(uintID(0), nil)}},
   131  					{rw: &conn{flags: dynDialedConn, node: newNode(uintID(1), nil)}},
   132  					{rw: &conn{flags: dynDialedConn, node: newNode(uintID(2), nil)}},
   133  					{rw: &conn{flags: dynDialedConn, node: newNode(uintID(3), nil)}},
   134  					{rw: &conn{flags: dynDialedConn, node: newNode(uintID(4), nil)}},
   135  				},
   136  				done: []task{
   137  					&dialTask{flags: dynDialedConn, dest: newNode(uintID(3), nil)},
   138  					&dialTask{flags: dynDialedConn, dest: newNode(uintID(4), nil)},
   139  				},
   140  			},
   141  			// No new dial tasks are launched in the this round because
   142  			// maxDynDials has been reached.
   143  			{
   144  				peers: []*Peer{
   145  					{rw: &conn{flags: staticDialedConn, node: newNode(uintID(0), nil)}},
   146  					{rw: &conn{flags: dynDialedConn, node: newNode(uintID(1), nil)}},
   147  					{rw: &conn{flags: dynDialedConn, node: newNode(uintID(2), nil)}},
   148  					{rw: &conn{flags: dynDialedConn, node: newNode(uintID(3), nil)}},
   149  					{rw: &conn{flags: dynDialedConn, node: newNode(uintID(4), nil)}},
   150  					{rw: &conn{flags: dynDialedConn, node: newNode(uintID(5), nil)}},
   151  				},
   152  				done: []task{
   153  					&dialTask{flags: dynDialedConn, dest: newNode(uintID(5), nil)},
   154  				},
   155  				new: []task{
   156  					&waitExpireTask{Duration: 14 * time.Second},
   157  				},
   158  			},
   159  			// In this round, the peer with id 2 drops off. The query
   160  			// results from last discovery lookup are reused.
   161  			{
   162  				peers: []*Peer{
   163  					{rw: &conn{flags: staticDialedConn, node: newNode(uintID(0), nil)}},
   164  					{rw: &conn{flags: dynDialedConn, node: newNode(uintID(1), nil)}},
   165  					{rw: &conn{flags: dynDialedConn, node: newNode(uintID(3), nil)}},
   166  					{rw: &conn{flags: dynDialedConn, node: newNode(uintID(4), nil)}},
   167  					{rw: &conn{flags: dynDialedConn, node: newNode(uintID(5), nil)}},
   168  				},
   169  				new: []task{},
   170  			},
   171  			// More peers (3,4) drop off and dial for ID 6 completes.
   172  			// The last query result from the discovery lookup is reused
   173  			// and a new one is spawned because more candidates are needed.
   174  			{
   175  				peers: []*Peer{
   176  					{rw: &conn{flags: staticDialedConn, node: newNode(uintID(0), nil)}},
   177  					{rw: &conn{flags: dynDialedConn, node: newNode(uintID(1), nil)}},
   178  					{rw: &conn{flags: dynDialedConn, node: newNode(uintID(5), nil)}},
   179  				},
   180  				done: []task{
   181  					&dialTask{flags: dynDialedConn, dest: newNode(uintID(6), nil)},
   182  				},
   183  				new: []task{
   184  					&dialTask{flags: dynDialedConn, dest: newNode(uintID(5), nil)},
   185  					&dialTask{flags: dynDialedConn, dest: newNode(uintID(7), nil)},
   186  				},
   187  			},
   188  			// Peer 7 is connected, but there still aren't enough dynamic peers
   189  			// (4 out of 5). However, a discovery is already running, so ensure
   190  			// no new is started.
   191  			{
   192  				peers: []*Peer{
   193  					{rw: &conn{flags: staticDialedConn, node: newNode(uintID(0), nil)}},
   194  					{rw: &conn{flags: dynDialedConn, node: newNode(uintID(1), nil)}},
   195  					{rw: &conn{flags: dynDialedConn, node: newNode(uintID(5), nil)}},
   196  					{rw: &conn{flags: dynDialedConn, node: newNode(uintID(7), nil)}},
   197  				},
   198  				done: []task{
   199  					&dialTask{flags: dynDialedConn, dest: newNode(uintID(7), nil)},
   200  				},
   201  			},
   202  			// Finish the running node discovery with an empty set. A new lookup
   203  			// should be immediately requested.
   204  			{
   205  				peers: []*Peer{
   206  					{rw: &conn{flags: staticDialedConn, node: newNode(uintID(0), nil)}},
   207  					{rw: &conn{flags: dynDialedConn, node: newNode(uintID(1), nil)}},
   208  					{rw: &conn{flags: dynDialedConn, node: newNode(uintID(5), nil)}},
   209  					{rw: &conn{flags: dynDialedConn, node: newNode(uintID(7), nil)}},
   210  				},
   211  				done: []task{
   212  					&discoverTask{},
   213  				},
   214  				new: []task{
   215  					&waitExpireTask{Duration: 14 * time.Second},
   216  				},
   217  			},
   218  		},
   219  	})
   220  }
   221  
   222  // Tests that bootnodes are dialed if no peers are connectd, but not otherwise.
   223  func TestDialStateDynDialBootnode(t *testing.T) {
   224  	bootnodes := []*enode.Node{
   225  		newNode(uintID(1), nil),
   226  		newNode(uintID(2), nil),
   227  		newNode(uintID(3), nil),
   228  	}
   229  	table := fakeTable{
   230  		newNode(uintID(4), nil),
   231  		newNode(uintID(5), nil),
   232  		newNode(uintID(6), nil),
   233  		newNode(uintID(7), nil),
   234  		newNode(uintID(8), nil),
   235  	}
   236  	runDialTest(t, dialtest{
   237  		init: newDialState(enode.ID{}, nil, bootnodes, table, 5, nil),
   238  		rounds: []round{
   239  			// 2 dynamic dials attempted, bootnodes pending fallback interval
   240  			{
   241  				new: []task{
   242  					&dialTask{flags: dynDialedConn, dest: newNode(uintID(4), nil)},
   243  					&dialTask{flags: dynDialedConn, dest: newNode(uintID(5), nil)},
   244  					&discoverTask{},
   245  				},
   246  			},
   247  			// No dials succeed, bootnodes still pending fallback interval
   248  			{
   249  				done: []task{
   250  					&dialTask{flags: dynDialedConn, dest: newNode(uintID(4), nil)},
   251  					&dialTask{flags: dynDialedConn, dest: newNode(uintID(5), nil)},
   252  				},
   253  			},
   254  			// No dials succeed, bootnodes still pending fallback interval
   255  			{},
   256  			// No dials succeed, 2 dynamic dials attempted and 1 bootnode too as fallback interval was reached
   257  			{
   258  				new: []task{
   259  					&dialTask{flags: dynDialedConn, dest: newNode(uintID(1), nil)},
   260  					&dialTask{flags: dynDialedConn, dest: newNode(uintID(4), nil)},
   261  					&dialTask{flags: dynDialedConn, dest: newNode(uintID(5), nil)},
   262  				},
   263  			},
   264  			// No dials succeed, 2nd bootnode is attempted
   265  			{
   266  				done: []task{
   267  					&dialTask{flags: dynDialedConn, dest: newNode(uintID(1), nil)},
   268  					&dialTask{flags: dynDialedConn, dest: newNode(uintID(4), nil)},
   269  					&dialTask{flags: dynDialedConn, dest: newNode(uintID(5), nil)},
   270  				},
   271  				new: []task{
   272  					&dialTask{flags: dynDialedConn, dest: newNode(uintID(2), nil)},
   273  				},
   274  			},
   275  			// No dials succeed, 3rd bootnode is attempted
   276  			{
   277  				done: []task{
   278  					&dialTask{flags: dynDialedConn, dest: newNode(uintID(2), nil)},
   279  				},
   280  				new: []task{
   281  					&dialTask{flags: dynDialedConn, dest: newNode(uintID(3), nil)},
   282  				},
   283  			},
   284  			// No dials succeed, 1st bootnode is attempted again, expired random nodes retried
   285  			{
   286  				done: []task{
   287  					&dialTask{flags: dynDialedConn, dest: newNode(uintID(3), nil)},
   288  				},
   289  				new: []task{
   290  					&dialTask{flags: dynDialedConn, dest: newNode(uintID(1), nil)},
   291  					&dialTask{flags: dynDialedConn, dest: newNode(uintID(4), nil)},
   292  					&dialTask{flags: dynDialedConn, dest: newNode(uintID(5), nil)},
   293  				},
   294  			},
   295  			// Random dial succeeds, no more bootnodes are attempted
   296  			{
   297  				peers: []*Peer{
   298  					{rw: &conn{flags: dynDialedConn, node: newNode(uintID(4), nil)}},
   299  				},
   300  				done: []task{
   301  					&dialTask{flags: dynDialedConn, dest: newNode(uintID(1), nil)},
   302  					&dialTask{flags: dynDialedConn, dest: newNode(uintID(4), nil)},
   303  					&dialTask{flags: dynDialedConn, dest: newNode(uintID(5), nil)},
   304  				},
   305  				new: []task{
   306  					&dialTask{flags: dynDialedConn, dest: newNode(uintID(4), nil)},
   307  				},
   308  			},
   309  		},
   310  	})
   311  }
   312  
   313  func TestDialStateDynDialFromTable(t *testing.T) {
   314  	// This table always returns the same random nodes
   315  	// in the order given below.
   316  	table := fakeTable{
   317  		newNode(uintID(1), nil),
   318  		newNode(uintID(2), nil),
   319  		newNode(uintID(3), nil),
   320  		newNode(uintID(4), nil),
   321  		newNode(uintID(5), nil),
   322  		newNode(uintID(6), nil),
   323  		newNode(uintID(7), nil),
   324  		newNode(uintID(8), nil),
   325  	}
   326  
   327  	runDialTest(t, dialtest{
   328  		init: newDialState(enode.ID{}, nil, nil, table, 10, nil),
   329  		rounds: []round{
   330  			// 5 out of 8 of the nodes returned by ReadRandomNodes are dialed.
   331  			{
   332  				new: []task{
   333  					&dialTask{flags: dynDialedConn, dest: newNode(uintID(1), nil)},
   334  					&dialTask{flags: dynDialedConn, dest: newNode(uintID(2), nil)},
   335  					&dialTask{flags: dynDialedConn, dest: newNode(uintID(3), nil)},
   336  					&dialTask{flags: dynDialedConn, dest: newNode(uintID(4), nil)},
   337  					&dialTask{flags: dynDialedConn, dest: newNode(uintID(5), nil)},
   338  					&discoverTask{},
   339  				},
   340  			},
   341  			// Dialing nodes 1,2 succeeds. Dials from the lookup are launched.
   342  			{
   343  				peers: []*Peer{
   344  					{rw: &conn{flags: dynDialedConn, node: newNode(uintID(1), nil)}},
   345  					{rw: &conn{flags: dynDialedConn, node: newNode(uintID(2), nil)}},
   346  				},
   347  				done: []task{
   348  					&dialTask{flags: dynDialedConn, dest: newNode(uintID(1), nil)},
   349  					&dialTask{flags: dynDialedConn, dest: newNode(uintID(2), nil)},
   350  					&discoverTask{results: []*enode.Node{
   351  						newNode(uintID(10), nil),
   352  						newNode(uintID(11), nil),
   353  						newNode(uintID(12), nil),
   354  					}},
   355  				},
   356  				new: []task{
   357  					&dialTask{flags: dynDialedConn, dest: newNode(uintID(1), nil)},
   358  					&dialTask{flags: dynDialedConn, dest: newNode(uintID(2), nil)},
   359  					&dialTask{flags: dynDialedConn, dest: newNode(uintID(10), nil)},
   360  					&dialTask{flags: dynDialedConn, dest: newNode(uintID(11), nil)},
   361  					&dialTask{flags: dynDialedConn, dest: newNode(uintID(12), nil)},
   362  				},
   363  			},
   364  			// Dialing nodes 3,4,5 fails. The dials from the lookup succeed.
   365  			{
   366  				peers: []*Peer{
   367  					{rw: &conn{flags: dynDialedConn, node: newNode(uintID(1), nil)}},
   368  					{rw: &conn{flags: dynDialedConn, node: newNode(uintID(2), nil)}},
   369  					{rw: &conn{flags: dynDialedConn, node: newNode(uintID(10), nil)}},
   370  					{rw: &conn{flags: dynDialedConn, node: newNode(uintID(11), nil)}},
   371  					{rw: &conn{flags: dynDialedConn, node: newNode(uintID(12), nil)}},
   372  				},
   373  				done: []task{
   374  					&dialTask{flags: dynDialedConn, dest: newNode(uintID(3), nil)},
   375  					&dialTask{flags: dynDialedConn, dest: newNode(uintID(4), nil)},
   376  					&dialTask{flags: dynDialedConn, dest: newNode(uintID(5), nil)},
   377  					&dialTask{flags: dynDialedConn, dest: newNode(uintID(10), nil)},
   378  					&dialTask{flags: dynDialedConn, dest: newNode(uintID(11), nil)},
   379  					&dialTask{flags: dynDialedConn, dest: newNode(uintID(12), nil)},
   380  				},
   381  				new: []task{
   382  					&discoverTask{},
   383  				},
   384  			},
   385  			// Waiting for expiry. No waitExpireTask is launched because the
   386  			// discovery query is still running.
   387  			{
   388  				peers: []*Peer{
   389  					{rw: &conn{flags: dynDialedConn, node: newNode(uintID(1), nil)}},
   390  					{rw: &conn{flags: dynDialedConn, node: newNode(uintID(2), nil)}},
   391  					{rw: &conn{flags: dynDialedConn, node: newNode(uintID(10), nil)}},
   392  					{rw: &conn{flags: dynDialedConn, node: newNode(uintID(11), nil)}},
   393  					{rw: &conn{flags: dynDialedConn, node: newNode(uintID(12), nil)}},
   394  				},
   395  			},
   396  			// Nodes 3,4 are not tried again because only the first two
   397  			// returned random nodes (nodes 1,2) are tried and they're
   398  			// already connected.
   399  			{
   400  				peers: []*Peer{
   401  					{rw: &conn{flags: dynDialedConn, node: newNode(uintID(1), nil)}},
   402  					{rw: &conn{flags: dynDialedConn, node: newNode(uintID(2), nil)}},
   403  					{rw: &conn{flags: dynDialedConn, node: newNode(uintID(10), nil)}},
   404  					{rw: &conn{flags: dynDialedConn, node: newNode(uintID(11), nil)}},
   405  					{rw: &conn{flags: dynDialedConn, node: newNode(uintID(12), nil)}},
   406  				},
   407  			},
   408  		},
   409  	})
   410  }
   411  
   412  func newNode(id enode.ID, ip net.IP) *enode.Node {
   413  	var r enr.Record
   414  	if ip != nil {
   415  		r.Set(enr.IP(ip))
   416  	}
   417  	return enode.SignNull(&r, id)
   418  }
   419  
   420  // This test checks that candidates that do not match the netrestrict list are not dialed.
   421  func TestDialStateNetRestrict(t *testing.T) {
   422  	// This table always returns the same random nodes
   423  	// in the order given below.
   424  	table := fakeTable{
   425  		newNode(uintID(1), net.ParseIP("127.0.0.1")),
   426  		newNode(uintID(2), net.ParseIP("127.0.0.2")),
   427  		newNode(uintID(3), net.ParseIP("127.0.0.3")),
   428  		newNode(uintID(4), net.ParseIP("127.0.0.4")),
   429  		newNode(uintID(5), net.ParseIP("127.0.2.5")),
   430  		newNode(uintID(6), net.ParseIP("127.0.2.6")),
   431  		newNode(uintID(7), net.ParseIP("127.0.2.7")),
   432  		newNode(uintID(8), net.ParseIP("127.0.2.8")),
   433  	}
   434  	restrict := new(netutil.Netlist)
   435  	restrict.Add("127.0.2.0/24")
   436  
   437  	runDialTest(t, dialtest{
   438  		init: newDialState(enode.ID{}, nil, nil, table, 10, restrict),
   439  		rounds: []round{
   440  			{
   441  				new: []task{
   442  					&dialTask{flags: dynDialedConn, dest: table[4]},
   443  					&discoverTask{},
   444  				},
   445  			},
   446  		},
   447  	})
   448  }
   449  
   450  // This test checks that static dials are launched.
   451  func TestDialStateStaticDial(t *testing.T) {
   452  	wantStatic := []*enode.Node{
   453  		newNode(uintID(1), nil),
   454  		newNode(uintID(2), nil),
   455  		newNode(uintID(3), nil),
   456  		newNode(uintID(4), nil),
   457  		newNode(uintID(5), nil),
   458  	}
   459  
   460  	runDialTest(t, dialtest{
   461  		init: newDialState(enode.ID{}, wantStatic, nil, fakeTable{}, 0, nil),
   462  		rounds: []round{
   463  			// Static dials are launched for the nodes that
   464  			// aren't yet connected.
   465  			{
   466  				peers: []*Peer{
   467  					{rw: &conn{flags: dynDialedConn, node: newNode(uintID(1), nil)}},
   468  					{rw: &conn{flags: dynDialedConn, node: newNode(uintID(2), nil)}},
   469  				},
   470  				new: []task{
   471  					&dialTask{flags: staticDialedConn, dest: newNode(uintID(1), nil)},
   472  					&dialTask{flags: staticDialedConn, dest: newNode(uintID(2), nil)},
   473  					&dialTask{flags: staticDialedConn, dest: newNode(uintID(3), nil)},
   474  					&dialTask{flags: staticDialedConn, dest: newNode(uintID(4), nil)},
   475  					&dialTask{flags: staticDialedConn, dest: newNode(uintID(5), nil)},
   476  				},
   477  			},
   478  			// No new tasks are launched in this round because all static
   479  			// nodes are either connected or still being dialed.
   480  			{
   481  				peers: []*Peer{
   482  					{rw: &conn{flags: dynDialedConn, node: newNode(uintID(1), nil)}},
   483  					{rw: &conn{flags: dynDialedConn, node: newNode(uintID(2), nil)}},
   484  					{rw: &conn{flags: staticDialedConn, node: newNode(uintID(3), nil)}},
   485  				},
   486  				new: []task{
   487  					&dialTask{flags: staticDialedConn, dest: newNode(uintID(3), nil)},
   488  				},
   489  				done: []task{
   490  					&dialTask{flags: staticDialedConn, dest: newNode(uintID(3), nil)},
   491  				},
   492  			},
   493  			// No new dial tasks are launched because all static
   494  			// nodes are now connected.
   495  			{
   496  				peers: []*Peer{
   497  					{rw: &conn{flags: dynDialedConn, node: newNode(uintID(1), nil)}},
   498  					{rw: &conn{flags: dynDialedConn, node: newNode(uintID(2), nil)}},
   499  					{rw: &conn{flags: staticDialedConn, node: newNode(uintID(3), nil)}},
   500  					{rw: &conn{flags: staticDialedConn, node: newNode(uintID(4), nil)}},
   501  					{rw: &conn{flags: staticDialedConn, node: newNode(uintID(5), nil)}},
   502  				},
   503  				done: []task{
   504  					&dialTask{flags: staticDialedConn, dest: newNode(uintID(4), nil)},
   505  					&dialTask{flags: staticDialedConn, dest: newNode(uintID(5), nil)},
   506  				},
   507  				new: []task{
   508  					&dialTask{flags: staticDialedConn, dest: newNode(uintID(4), nil)},
   509  					&dialTask{flags: staticDialedConn, dest: newNode(uintID(5), nil)},
   510  				},
   511  			},
   512  			// Wait a round for dial history to expire, no new tasks should spawn.
   513  			{
   514  				peers: []*Peer{
   515  					{rw: &conn{flags: dynDialedConn, node: newNode(uintID(1), nil)}},
   516  					{rw: &conn{flags: dynDialedConn, node: newNode(uintID(2), nil)}},
   517  					{rw: &conn{flags: staticDialedConn, node: newNode(uintID(3), nil)}},
   518  					{rw: &conn{flags: staticDialedConn, node: newNode(uintID(4), nil)}},
   519  					{rw: &conn{flags: staticDialedConn, node: newNode(uintID(5), nil)}},
   520  				},
   521  			},
   522  			// If a static node is dropped, it should be immediately redialed,
   523  			// irrespective whether it was originally static or dynamic.
   524  			{
   525  				peers: []*Peer{
   526  					{rw: &conn{flags: dynDialedConn, node: newNode(uintID(1), nil)}},
   527  					{rw: &conn{flags: staticDialedConn, node: newNode(uintID(3), nil)}},
   528  					{rw: &conn{flags: staticDialedConn, node: newNode(uintID(5), nil)}},
   529  				},
   530  				new: []task{},
   531  			},
   532  		},
   533  	})
   534  }
   535  
   536  // This test checks that static peers will be redialed immediately if they were re-added to a static list.
   537  func TestDialStaticAfterReset(t *testing.T) {
   538  	wantStatic := []*enode.Node{
   539  		newNode(uintID(1), nil),
   540  		newNode(uintID(2), nil),
   541  	}
   542  
   543  	rounds := []round{
   544  		// Static dials are launched for the nodes that aren't yet connected.
   545  		{
   546  			peers: nil,
   547  			new: []task{
   548  				&dialTask{flags: staticDialedConn, dest: newNode(uintID(1), nil)},
   549  				&dialTask{flags: staticDialedConn, dest: newNode(uintID(2), nil)},
   550  			},
   551  		},
   552  		// No new dial tasks, all peers are connected.
   553  		{
   554  			peers: []*Peer{
   555  				{rw: &conn{flags: staticDialedConn, node: newNode(uintID(1), nil)}},
   556  				{rw: &conn{flags: staticDialedConn, node: newNode(uintID(2), nil)}},
   557  			},
   558  			done: []task{
   559  				&dialTask{flags: staticDialedConn, dest: newNode(uintID(1), nil)},
   560  				&dialTask{flags: staticDialedConn, dest: newNode(uintID(2), nil)},
   561  			},
   562  			new: []task{
   563  				&dialTask{flags: staticDialedConn, dest: newNode(uintID(1), nil)},
   564  				&dialTask{flags: staticDialedConn, dest: newNode(uintID(2), nil)},
   565  			},
   566  		},
   567  	}
   568  	dTest := dialtest{
   569  		init:   newDialState(enode.ID{}, wantStatic, nil, fakeTable{}, 0, nil),
   570  		rounds: rounds,
   571  	}
   572  	runDialTest(t, dTest)
   573  	for _, n := range wantStatic {
   574  		dTest.init.removeStatic(n)
   575  		dTest.init.addStatic(n)
   576  		delete(dTest.init.dialing, n.ID())
   577  	}
   578  
   579  	// without removing peers they will be considered recently dialed
   580  	runDialTest(t, dTest)
   581  }
   582  
   583  // This test checks that past dials are not retried for some time.
   584  func TestDialStateCache(t *testing.T) {
   585  	wantStatic := []*enode.Node{
   586  		newNode(uintID(1), nil),
   587  		newNode(uintID(2), nil),
   588  		newNode(uintID(3), nil),
   589  	}
   590  
   591  	runDialTest(t, dialtest{
   592  		init: newDialState(enode.ID{}, wantStatic, nil, fakeTable{}, 0, nil),
   593  		rounds: []round{
   594  			// Static dials are launched for the nodes that
   595  			// aren't yet connected.
   596  			{
   597  				peers: nil,
   598  				new: []task{
   599  					&dialTask{flags: staticDialedConn, dest: newNode(uintID(1), nil)},
   600  					&dialTask{flags: staticDialedConn, dest: newNode(uintID(2), nil)},
   601  					&dialTask{flags: staticDialedConn, dest: newNode(uintID(3), nil)},
   602  				},
   603  			},
   604  			// No new tasks are launched in this round because all static
   605  			// nodes are either connected or still being dialed.
   606  			{
   607  				peers: []*Peer{
   608  					{rw: &conn{flags: staticDialedConn, node: newNode(uintID(1), nil)}},
   609  					{rw: &conn{flags: staticDialedConn, node: newNode(uintID(2), nil)}},
   610  				},
   611  				done: []task{
   612  					&dialTask{flags: staticDialedConn, dest: newNode(uintID(1), nil)},
   613  					&dialTask{flags: staticDialedConn, dest: newNode(uintID(2), nil)},
   614  				},
   615  				new: []task{
   616  					&dialTask{flags: staticDialedConn, dest: newNode(uintID(1), nil)},
   617  					&dialTask{flags: staticDialedConn, dest: newNode(uintID(2), nil)},
   618  				},
   619  			},
   620  			// A salvage task is launched to wait for node 3's history
   621  			// entry to expire.
   622  			{
   623  				peers: []*Peer{
   624  					{rw: &conn{flags: dynDialedConn, node: newNode(uintID(1), nil)}},
   625  					{rw: &conn{flags: dynDialedConn, node: newNode(uintID(2), nil)}},
   626  				},
   627  				done: []task{
   628  					&dialTask{flags: staticDialedConn, dest: newNode(uintID(3), nil)},
   629  				},
   630  			},
   631  			// Still waiting for node 3's entry to expire in the cache.
   632  			{
   633  				peers: []*Peer{
   634  					{rw: &conn{flags: dynDialedConn, node: newNode(uintID(1), nil)}},
   635  					{rw: &conn{flags: dynDialedConn, node: newNode(uintID(2), nil)}},
   636  				},
   637  			},
   638  			// The cache entry for node 3 has expired and is retried.
   639  			{
   640  				peers: []*Peer{
   641  					{rw: &conn{flags: dynDialedConn, node: newNode(uintID(1), nil)}},
   642  					{rw: &conn{flags: dynDialedConn, node: newNode(uintID(2), nil)}},
   643  				},
   644  				new: []task{
   645  					&dialTask{flags: staticDialedConn, dest: newNode(uintID(3), nil)},
   646  				},
   647  			},
   648  		},
   649  	})
   650  }
   651  
   652  func TestDialResolve(t *testing.T) {
   653  	resolved := newNode(uintID(1), net.IP{127, 0, 55, 234})
   654  	table := &resolveMock{answer: resolved}
   655  	state := newDialState(enode.ID{}, nil, nil, table, 0, nil)
   656  
   657  	// Check that the task is generated with an incomplete ID.
   658  	dest := newNode(uintID(1), nil)
   659  	state.addStatic(dest)
   660  	tasks := state.newTasks(0, nil, time.Time{})
   661  	if !reflect.DeepEqual(tasks, []task{&dialTask{flags: staticDialedConn, dest: dest}}) {
   662  		t.Fatalf("expected dial task, got %#v", tasks)
   663  	}
   664  
   665  	// Now run the task, it should resolve the ID once.
   666  	config := Config{Dialer: TCPDialer{&net.Dialer{Deadline: time.Now().Add(-5 * time.Minute)}}}
   667  	srv := &Server{ntab: table, Config: config}
   668  	tasks[0].Do(srv)
   669  	if !reflect.DeepEqual(table.resolveCalls, []*enode.Node{dest}) {
   670  		t.Fatalf("wrong resolve calls, got %v", table.resolveCalls)
   671  	}
   672  
   673  	// Report it as done to the dialer, which should update the static node record.
   674  	state.taskDone(tasks[0], time.Now())
   675  	if state.static[uintID(1)].dest != resolved {
   676  		t.Fatalf("state.dest not updated")
   677  	}
   678  }
   679  
   680  // compares task lists but doesn't care about the order.
   681  func sametasks(a, b []task) bool {
   682  	if len(a) != len(b) {
   683  		return false
   684  	}
   685  next:
   686  	for _, ta := range a {
   687  		for _, tb := range b {
   688  			if reflect.DeepEqual(ta, tb) {
   689  				continue next
   690  			}
   691  		}
   692  		return false
   693  	}
   694  	return true
   695  }
   696  
   697  func uintID(i uint32) enode.ID {
   698  	var id enode.ID
   699  	binary.BigEndian.PutUint32(id[:], i)
   700  	return id
   701  }
   702  
   703  // implements discoverTable for TestDialResolve
   704  type resolveMock struct {
   705  	resolveCalls []*enode.Node
   706  	answer       *enode.Node
   707  }
   708  
   709  func (t *resolveMock) Resolve(n *enode.Node) *enode.Node {
   710  	t.resolveCalls = append(t.resolveCalls, n)
   711  	return t.answer
   712  }
   713  
   714  func (t *resolveMock) Self() *enode.Node                     { return new(enode.Node) }
   715  func (t *resolveMock) Close()                                {}
   716  func (t *resolveMock) LookupRandom() []*enode.Node           { return nil }
   717  func (t *resolveMock) ReadRandomNodes(buf []*enode.Node) int { return 0 }