|
|
@@ -73,7 +73,7 @@ func runDialTest(t *testing.T, test dialtest) {
|
|
|
t.Errorf("ERROR round %d: got %v\nwant %v\nstate: %v\nrunning: %v",
|
|
|
i, spew.Sdump(new), spew.Sdump(round.new), spew.Sdump(test.init), spew.Sdump(running))
|
|
|
}
|
|
|
- t.Logf("round %d new tasks: %s", i, strings.TrimSpace(spew.Sdump(new)))
|
|
|
+ t.Logf("round %d (running %d) new tasks: %s", i, running, strings.TrimSpace(spew.Sdump(new)))
|
|
|
|
|
|
// Time advances by 16 seconds on every round.
|
|
|
vtime = vtime.Add(16 * time.Second)
|
|
|
@@ -81,19 +81,11 @@ func runDialTest(t *testing.T, test dialtest) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-type fakeTable []*enode.Node
|
|
|
-
|
|
|
-func (t fakeTable) Self() *enode.Node { return new(enode.Node) }
|
|
|
-func (t fakeTable) Close() {}
|
|
|
-func (t fakeTable) LookupRandom() []*enode.Node { return nil }
|
|
|
-func (t fakeTable) Resolve(*enode.Node) *enode.Node { return nil }
|
|
|
-func (t fakeTable) ReadRandomNodes(buf []*enode.Node) int { return copy(buf, t) }
|
|
|
-
|
|
|
// This test checks that dynamic dials are launched from discovery results.
|
|
|
func TestDialStateDynDial(t *testing.T) {
|
|
|
config := &Config{Logger: testlog.Logger(t, log.LvlTrace)}
|
|
|
runDialTest(t, dialtest{
|
|
|
- init: newDialState(enode.ID{}, fakeTable{}, 5, config),
|
|
|
+ init: newDialState(enode.ID{}, 5, config),
|
|
|
rounds: []round{
|
|
|
// A discovery query is launched.
|
|
|
{
|
|
|
@@ -102,7 +94,9 @@ func TestDialStateDynDial(t *testing.T) {
|
|
|
{rw: &conn{flags: dynDialedConn, node: newNode(uintID(1), nil)}},
|
|
|
{rw: &conn{flags: dynDialedConn, node: newNode(uintID(2), nil)}},
|
|
|
},
|
|
|
- new: []task{&discoverTask{}},
|
|
|
+ new: []task{
|
|
|
+ &discoverTask{want: 3},
|
|
|
+ },
|
|
|
},
|
|
|
// Dynamic dials are launched when it completes.
|
|
|
{
|
|
|
@@ -188,7 +182,7 @@ func TestDialStateDynDial(t *testing.T) {
|
|
|
},
|
|
|
new: []task{
|
|
|
&dialTask{flags: dynDialedConn, dest: newNode(uintID(7), nil)},
|
|
|
- &discoverTask{},
|
|
|
+ &discoverTask{want: 2},
|
|
|
},
|
|
|
},
|
|
|
// Peer 7 is connected, but there still aren't enough dynamic peers
|
|
|
@@ -218,7 +212,7 @@ func TestDialStateDynDial(t *testing.T) {
|
|
|
&discoverTask{},
|
|
|
},
|
|
|
new: []task{
|
|
|
- &discoverTask{},
|
|
|
+ &discoverTask{want: 2},
|
|
|
},
|
|
|
},
|
|
|
},
|
|
|
@@ -235,35 +229,37 @@ func TestDialStateDynDialBootnode(t *testing.T) {
|
|
|
},
|
|
|
Logger: testlog.Logger(t, log.LvlTrace),
|
|
|
}
|
|
|
- table := fakeTable{
|
|
|
- newNode(uintID(4), nil),
|
|
|
- newNode(uintID(5), nil),
|
|
|
- newNode(uintID(6), nil),
|
|
|
- newNode(uintID(7), nil),
|
|
|
- newNode(uintID(8), nil),
|
|
|
- }
|
|
|
runDialTest(t, dialtest{
|
|
|
- init: newDialState(enode.ID{}, table, 5, config),
|
|
|
+ init: newDialState(enode.ID{}, 5, config),
|
|
|
rounds: []round{
|
|
|
- // 2 dynamic dials attempted, bootnodes pending fallback interval
|
|
|
{
|
|
|
new: []task{
|
|
|
- &dialTask{flags: dynDialedConn, dest: newNode(uintID(4), nil)},
|
|
|
- &dialTask{flags: dynDialedConn, dest: newNode(uintID(5), nil)},
|
|
|
- &discoverTask{},
|
|
|
+ &discoverTask{want: 5},
|
|
|
},
|
|
|
},
|
|
|
- // No dials succeed, bootnodes still pending fallback interval
|
|
|
{
|
|
|
done: []task{
|
|
|
+ &discoverTask{
|
|
|
+ results: []*enode.Node{
|
|
|
+ newNode(uintID(4), nil),
|
|
|
+ newNode(uintID(5), nil),
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ new: []task{
|
|
|
&dialTask{flags: dynDialedConn, dest: newNode(uintID(4), nil)},
|
|
|
&dialTask{flags: dynDialedConn, dest: newNode(uintID(5), nil)},
|
|
|
+ &discoverTask{want: 3},
|
|
|
},
|
|
|
},
|
|
|
// No dials succeed, bootnodes still pending fallback interval
|
|
|
{},
|
|
|
- // No dials succeed, 2 dynamic dials attempted and 1 bootnode too as fallback interval was reached
|
|
|
+ // 1 bootnode attempted as fallback interval was reached
|
|
|
{
|
|
|
+ done: []task{
|
|
|
+ &dialTask{flags: dynDialedConn, dest: newNode(uintID(4), nil)},
|
|
|
+ &dialTask{flags: dynDialedConn, dest: newNode(uintID(5), nil)},
|
|
|
+ },
|
|
|
new: []task{
|
|
|
&dialTask{flags: dynDialedConn, dest: newNode(uintID(1), nil)},
|
|
|
},
|
|
|
@@ -275,15 +271,12 @@ func TestDialStateDynDialBootnode(t *testing.T) {
|
|
|
},
|
|
|
new: []task{
|
|
|
&dialTask{flags: dynDialedConn, dest: newNode(uintID(2), nil)},
|
|
|
- &dialTask{flags: dynDialedConn, dest: newNode(uintID(4), nil)},
|
|
|
- &dialTask{flags: dynDialedConn, dest: newNode(uintID(5), nil)},
|
|
|
},
|
|
|
},
|
|
|
// No dials succeed, 3rd bootnode is attempted
|
|
|
{
|
|
|
done: []task{
|
|
|
&dialTask{flags: dynDialedConn, dest: newNode(uintID(2), nil)},
|
|
|
- &dialTask{flags: dynDialedConn, dest: newNode(uintID(5), nil)},
|
|
|
},
|
|
|
new: []task{
|
|
|
&dialTask{flags: dynDialedConn, dest: newNode(uintID(3), nil)},
|
|
|
@@ -293,115 +286,19 @@ func TestDialStateDynDialBootnode(t *testing.T) {
|
|
|
{
|
|
|
done: []task{
|
|
|
&dialTask{flags: dynDialedConn, dest: newNode(uintID(3), nil)},
|
|
|
- },
|
|
|
- new: []task{},
|
|
|
- },
|
|
|
- // Random dial succeeds, no more bootnodes are attempted
|
|
|
- {
|
|
|
- new: []task{
|
|
|
- &waitExpireTask{3 * time.Second},
|
|
|
- },
|
|
|
- peers: []*Peer{
|
|
|
- {rw: &conn{flags: dynDialedConn, node: newNode(uintID(4), nil)}},
|
|
|
- },
|
|
|
- done: []task{
|
|
|
- &dialTask{flags: dynDialedConn, dest: newNode(uintID(1), nil)},
|
|
|
- &dialTask{flags: dynDialedConn, dest: newNode(uintID(4), nil)},
|
|
|
- },
|
|
|
- },
|
|
|
- },
|
|
|
- })
|
|
|
-}
|
|
|
-
|
|
|
-func TestDialStateDynDialFromTable(t *testing.T) {
|
|
|
- // This table always returns the same random nodes
|
|
|
- // in the order given below.
|
|
|
- table := fakeTable{
|
|
|
- newNode(uintID(1), nil),
|
|
|
- newNode(uintID(2), nil),
|
|
|
- newNode(uintID(3), nil),
|
|
|
- newNode(uintID(4), nil),
|
|
|
- newNode(uintID(5), nil),
|
|
|
- newNode(uintID(6), nil),
|
|
|
- newNode(uintID(7), nil),
|
|
|
- newNode(uintID(8), nil),
|
|
|
- }
|
|
|
-
|
|
|
- runDialTest(t, dialtest{
|
|
|
- init: newDialState(enode.ID{}, table, 10, &Config{Logger: testlog.Logger(t, log.LvlTrace)}),
|
|
|
- rounds: []round{
|
|
|
- // 5 out of 8 of the nodes returned by ReadRandomNodes are dialed.
|
|
|
- {
|
|
|
- new: []task{
|
|
|
- &dialTask{flags: dynDialedConn, dest: newNode(uintID(1), nil)},
|
|
|
- &dialTask{flags: dynDialedConn, dest: newNode(uintID(2), nil)},
|
|
|
- &dialTask{flags: dynDialedConn, dest: newNode(uintID(3), nil)},
|
|
|
- &dialTask{flags: dynDialedConn, dest: newNode(uintID(4), nil)},
|
|
|
- &dialTask{flags: dynDialedConn, dest: newNode(uintID(5), nil)},
|
|
|
- &discoverTask{},
|
|
|
- },
|
|
|
- },
|
|
|
- // Dialing nodes 1,2 succeeds. Dials from the lookup are launched.
|
|
|
- {
|
|
|
- peers: []*Peer{
|
|
|
- {rw: &conn{flags: dynDialedConn, node: newNode(uintID(1), nil)}},
|
|
|
- {rw: &conn{flags: dynDialedConn, node: newNode(uintID(2), nil)}},
|
|
|
- },
|
|
|
- done: []task{
|
|
|
- &dialTask{flags: dynDialedConn, dest: newNode(uintID(1), nil)},
|
|
|
- &dialTask{flags: dynDialedConn, dest: newNode(uintID(2), nil)},
|
|
|
&discoverTask{results: []*enode.Node{
|
|
|
- newNode(uintID(10), nil),
|
|
|
- newNode(uintID(11), nil),
|
|
|
- newNode(uintID(12), nil),
|
|
|
+ newNode(uintID(6), nil),
|
|
|
}},
|
|
|
},
|
|
|
new: []task{
|
|
|
- &dialTask{flags: dynDialedConn, dest: newNode(uintID(10), nil)},
|
|
|
- &dialTask{flags: dynDialedConn, dest: newNode(uintID(11), nil)},
|
|
|
- &dialTask{flags: dynDialedConn, dest: newNode(uintID(12), nil)},
|
|
|
- &discoverTask{},
|
|
|
- },
|
|
|
- },
|
|
|
- // Dialing nodes 3,4,5 fails. The dials from the lookup succeed.
|
|
|
- {
|
|
|
- peers: []*Peer{
|
|
|
- {rw: &conn{flags: dynDialedConn, node: newNode(uintID(1), nil)}},
|
|
|
- {rw: &conn{flags: dynDialedConn, node: newNode(uintID(2), nil)}},
|
|
|
- {rw: &conn{flags: dynDialedConn, node: newNode(uintID(10), nil)}},
|
|
|
- {rw: &conn{flags: dynDialedConn, node: newNode(uintID(11), nil)}},
|
|
|
- {rw: &conn{flags: dynDialedConn, node: newNode(uintID(12), nil)}},
|
|
|
- },
|
|
|
- done: []task{
|
|
|
- &dialTask{flags: dynDialedConn, dest: newNode(uintID(3), nil)},
|
|
|
- &dialTask{flags: dynDialedConn, dest: newNode(uintID(4), nil)},
|
|
|
- &dialTask{flags: dynDialedConn, dest: newNode(uintID(5), nil)},
|
|
|
- &dialTask{flags: dynDialedConn, dest: newNode(uintID(10), nil)},
|
|
|
- &dialTask{flags: dynDialedConn, dest: newNode(uintID(11), nil)},
|
|
|
- &dialTask{flags: dynDialedConn, dest: newNode(uintID(12), nil)},
|
|
|
+ &dialTask{flags: dynDialedConn, dest: newNode(uintID(6), nil)},
|
|
|
+ &discoverTask{want: 4},
|
|
|
},
|
|
|
},
|
|
|
- // Waiting for expiry. No waitExpireTask is launched because the
|
|
|
- // discovery query is still running.
|
|
|
+ // Random dial succeeds, no more bootnodes are attempted
|
|
|
{
|
|
|
peers: []*Peer{
|
|
|
- {rw: &conn{flags: dynDialedConn, node: newNode(uintID(1), nil)}},
|
|
|
- {rw: &conn{flags: dynDialedConn, node: newNode(uintID(2), nil)}},
|
|
|
- {rw: &conn{flags: dynDialedConn, node: newNode(uintID(10), nil)}},
|
|
|
- {rw: &conn{flags: dynDialedConn, node: newNode(uintID(11), nil)}},
|
|
|
- {rw: &conn{flags: dynDialedConn, node: newNode(uintID(12), nil)}},
|
|
|
- },
|
|
|
- },
|
|
|
- // Nodes 3,4 are not tried again because only the first two
|
|
|
- // returned random nodes (nodes 1,2) are tried and they're
|
|
|
- // already connected.
|
|
|
- {
|
|
|
- peers: []*Peer{
|
|
|
- {rw: &conn{flags: dynDialedConn, node: newNode(uintID(1), nil)}},
|
|
|
- {rw: &conn{flags: dynDialedConn, node: newNode(uintID(2), nil)}},
|
|
|
- {rw: &conn{flags: dynDialedConn, node: newNode(uintID(10), nil)}},
|
|
|
- {rw: &conn{flags: dynDialedConn, node: newNode(uintID(11), nil)}},
|
|
|
- {rw: &conn{flags: dynDialedConn, node: newNode(uintID(12), nil)}},
|
|
|
+ {rw: &conn{flags: dynDialedConn, node: newNode(uintID(6), nil)}},
|
|
|
},
|
|
|
},
|
|
|
},
|
|
|
@@ -416,11 +313,11 @@ func newNode(id enode.ID, ip net.IP) *enode.Node {
|
|
|
return enode.SignNull(&r, id)
|
|
|
}
|
|
|
|
|
|
-// This test checks that candidates that do not match the netrestrict list are not dialed.
|
|
|
+// // This test checks that candidates that do not match the netrestrict list are not dialed.
|
|
|
func TestDialStateNetRestrict(t *testing.T) {
|
|
|
// This table always returns the same random nodes
|
|
|
// in the order given below.
|
|
|
- table := fakeTable{
|
|
|
+ nodes := []*enode.Node{
|
|
|
newNode(uintID(1), net.ParseIP("127.0.0.1")),
|
|
|
newNode(uintID(2), net.ParseIP("127.0.0.2")),
|
|
|
newNode(uintID(3), net.ParseIP("127.0.0.3")),
|
|
|
@@ -434,12 +331,23 @@ func TestDialStateNetRestrict(t *testing.T) {
|
|
|
restrict.Add("127.0.2.0/24")
|
|
|
|
|
|
runDialTest(t, dialtest{
|
|
|
- init: newDialState(enode.ID{}, table, 10, &Config{NetRestrict: restrict}),
|
|
|
+ init: newDialState(enode.ID{}, 10, &Config{NetRestrict: restrict}),
|
|
|
rounds: []round{
|
|
|
{
|
|
|
new: []task{
|
|
|
- &dialTask{flags: dynDialedConn, dest: table[4]},
|
|
|
- &discoverTask{},
|
|
|
+ &discoverTask{want: 10},
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ done: []task{
|
|
|
+ &discoverTask{results: nodes},
|
|
|
+ },
|
|
|
+ new: []task{
|
|
|
+ &dialTask{flags: dynDialedConn, dest: nodes[4]},
|
|
|
+ &dialTask{flags: dynDialedConn, dest: nodes[5]},
|
|
|
+ &dialTask{flags: dynDialedConn, dest: nodes[6]},
|
|
|
+ &dialTask{flags: dynDialedConn, dest: nodes[7]},
|
|
|
+ &discoverTask{want: 6},
|
|
|
},
|
|
|
},
|
|
|
},
|
|
|
@@ -459,7 +367,7 @@ func TestDialStateStaticDial(t *testing.T) {
|
|
|
Logger: testlog.Logger(t, log.LvlTrace),
|
|
|
}
|
|
|
runDialTest(t, dialtest{
|
|
|
- init: newDialState(enode.ID{}, fakeTable{}, 0, config),
|
|
|
+ init: newDialState(enode.ID{}, 0, config),
|
|
|
rounds: []round{
|
|
|
// Static dials are launched for the nodes that
|
|
|
// aren't yet connected.
|
|
|
@@ -544,7 +452,7 @@ func TestDialStateCache(t *testing.T) {
|
|
|
Logger: testlog.Logger(t, log.LvlTrace),
|
|
|
}
|
|
|
runDialTest(t, dialtest{
|
|
|
- init: newDialState(enode.ID{}, fakeTable{}, 0, config),
|
|
|
+ init: newDialState(enode.ID{}, 0, config),
|
|
|
rounds: []round{
|
|
|
// Static dials are launched for the nodes that
|
|
|
// aren't yet connected.
|
|
|
@@ -618,8 +526,8 @@ func TestDialResolve(t *testing.T) {
|
|
|
Dialer: TCPDialer{&net.Dialer{Deadline: time.Now().Add(-5 * time.Minute)}},
|
|
|
}
|
|
|
resolved := newNode(uintID(1), net.IP{127, 0, 55, 234})
|
|
|
- table := &resolveMock{answer: resolved}
|
|
|
- state := newDialState(enode.ID{}, table, 0, config)
|
|
|
+ resolver := &resolveMock{answer: resolved}
|
|
|
+ state := newDialState(enode.ID{}, 0, config)
|
|
|
|
|
|
// Check that the task is generated with an incomplete ID.
|
|
|
dest := newNode(uintID(1), nil)
|
|
|
@@ -630,10 +538,14 @@ func TestDialResolve(t *testing.T) {
|
|
|
}
|
|
|
|
|
|
// Now run the task, it should resolve the ID once.
|
|
|
- srv := &Server{ntab: table, log: config.Logger, Config: *config}
|
|
|
+ srv := &Server{
|
|
|
+ Config: *config,
|
|
|
+ log: config.Logger,
|
|
|
+ staticNodeResolver: resolver,
|
|
|
+ }
|
|
|
tasks[0].Do(srv)
|
|
|
- if !reflect.DeepEqual(table.resolveCalls, []*enode.Node{dest}) {
|
|
|
- t.Fatalf("wrong resolve calls, got %v", table.resolveCalls)
|
|
|
+ if !reflect.DeepEqual(resolver.calls, []*enode.Node{dest}) {
|
|
|
+ t.Fatalf("wrong resolve calls, got %v", resolver.calls)
|
|
|
}
|
|
|
|
|
|
// Report it as done to the dialer, which should update the static node record.
|
|
|
@@ -666,18 +578,13 @@ func uintID(i uint32) enode.ID {
|
|
|
return id
|
|
|
}
|
|
|
|
|
|
-// implements discoverTable for TestDialResolve
|
|
|
+// for TestDialResolve
|
|
|
type resolveMock struct {
|
|
|
- resolveCalls []*enode.Node
|
|
|
- answer *enode.Node
|
|
|
+ calls []*enode.Node
|
|
|
+ answer *enode.Node
|
|
|
}
|
|
|
|
|
|
func (t *resolveMock) Resolve(n *enode.Node) *enode.Node {
|
|
|
- t.resolveCalls = append(t.resolveCalls, n)
|
|
|
+ t.calls = append(t.calls, n)
|
|
|
return t.answer
|
|
|
}
|
|
|
-
|
|
|
-func (t *resolveMock) Self() *enode.Node { return new(enode.Node) }
|
|
|
-func (t *resolveMock) Close() {}
|
|
|
-func (t *resolveMock) LookupRandom() []*enode.Node { return nil }
|
|
|
-func (t *resolveMock) ReadRandomNodes(buf []*enode.Node) int { return 0 }
|