You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

788 lines
20 KiB

p2p: file descriptor leaks (#3150) * close peer's connection to avoid fd leak Fixes #2967 * rename peer#Addr to RemoteAddr * fix test * fixes after Ethan's review * bring back the check * changelog entry * write a test for switch#acceptRoutine * increase timeouts? :( * remove extra assertNPeersWithTimeout * simplify test * assert number of peers (just to be safe) * Cleanup in OnStop * run tests with verbose flag on CircleCI * spawn a reading routine to prevent connection from closing * get port from the listener random port is faster, but often results in ``` panic: listen tcp 127.0.0.1:44068: bind: address already in use [recovered] panic: listen tcp 127.0.0.1:44068: bind: address already in use goroutine 79 [running]: testing.tRunner.func1(0xc0001bd600) /usr/local/go/src/testing/testing.go:792 +0x387 panic(0x974d20, 0xc0001b0500) /usr/local/go/src/runtime/panic.go:513 +0x1b9 github.com/tendermint/tendermint/p2p.MakeSwitch(0xc0000f42a0, 0x0, 0x9fb9cc, 0x9, 0x9fc346, 0xb, 0xb42128, 0x0, 0x0, 0x0, ...) /home/vagrant/go/src/github.com/tendermint/tendermint/p2p/test_util.go:182 +0xa28 github.com/tendermint/tendermint/p2p.MakeConnectedSwitches(0xc0000f42a0, 0x2, 0xb42128, 0xb41eb8, 0x4f1205, 0xc0001bed80, 0x4f16ed) /home/vagrant/go/src/github.com/tendermint/tendermint/p2p/test_util.go:75 +0xf9 github.com/tendermint/tendermint/p2p.MakeSwitchPair(0xbb8d20, 0xc0001bd600, 0xb42128, 0x2f7, 0x4f16c0) /home/vagrant/go/src/github.com/tendermint/tendermint/p2p/switch_test.go:94 +0x4c github.com/tendermint/tendermint/p2p.TestSwitches(0xc0001bd600) /home/vagrant/go/src/github.com/tendermint/tendermint/p2p/switch_test.go:117 +0x58 testing.tRunner(0xc0001bd600, 0xb42038) /usr/local/go/src/testing/testing.go:827 +0xbf created by testing.(*T).Run /usr/local/go/src/testing/testing.go:878 +0x353 exit status 2 FAIL github.com/tendermint/tendermint/p2p 0.350s ```
6 years ago
p2p: file descriptor leaks (#3150) * close peer's connection to avoid fd leak Fixes #2967 * rename peer#Addr to RemoteAddr * fix test * fixes after Ethan's review * bring back the check * changelog entry * write a test for switch#acceptRoutine * increase timeouts? :( * remove extra assertNPeersWithTimeout * simplify test * assert number of peers (just to be safe) * Cleanup in OnStop * run tests with verbose flag on CircleCI * spawn a reading routine to prevent connection from closing * get port from the listener random port is faster, but often results in ``` panic: listen tcp 127.0.0.1:44068: bind: address already in use [recovered] panic: listen tcp 127.0.0.1:44068: bind: address already in use goroutine 79 [running]: testing.tRunner.func1(0xc0001bd600) /usr/local/go/src/testing/testing.go:792 +0x387 panic(0x974d20, 0xc0001b0500) /usr/local/go/src/runtime/panic.go:513 +0x1b9 github.com/tendermint/tendermint/p2p.MakeSwitch(0xc0000f42a0, 0x0, 0x9fb9cc, 0x9, 0x9fc346, 0xb, 0xb42128, 0x0, 0x0, 0x0, ...) /home/vagrant/go/src/github.com/tendermint/tendermint/p2p/test_util.go:182 +0xa28 github.com/tendermint/tendermint/p2p.MakeConnectedSwitches(0xc0000f42a0, 0x2, 0xb42128, 0xb41eb8, 0x4f1205, 0xc0001bed80, 0x4f16ed) /home/vagrant/go/src/github.com/tendermint/tendermint/p2p/test_util.go:75 +0xf9 github.com/tendermint/tendermint/p2p.MakeSwitchPair(0xbb8d20, 0xc0001bd600, 0xb42128, 0x2f7, 0x4f16c0) /home/vagrant/go/src/github.com/tendermint/tendermint/p2p/switch_test.go:94 +0x4c github.com/tendermint/tendermint/p2p.TestSwitches(0xc0001bd600) /home/vagrant/go/src/github.com/tendermint/tendermint/p2p/switch_test.go:117 +0x58 testing.tRunner(0xc0001bd600, 0xb42038) /usr/local/go/src/testing/testing.go:827 +0xbf created by testing.(*T).Run /usr/local/go/src/testing/testing.go:878 +0x353 exit status 2 FAIL github.com/tendermint/tendermint/p2p 0.350s ```
6 years ago
lint: Enable Golint (#4212) * Fix many golint errors * Fix golint errors in the 'lite' package * Don't export Pool.store * Fix typo * Revert unwanted changes * Fix errors in counter package * Fix linter errors in kvstore package * Fix linter error in example package * Fix error in tests package * Fix linter errors in v2 package * Fix linter errors in consensus package * Fix linter errors in evidence package * Fix linter error in fail package * Fix linter errors in query package * Fix linter errors in core package * Fix linter errors in node package * Fix linter errors in mempool package * Fix linter error in conn package * Fix linter errors in pex package * Rename PEXReactor export to Reactor * Fix linter errors in trust package * Fix linter errors in upnp package * Fix linter errors in p2p package * Fix linter errors in proxy package * Fix linter errors in mock_test package * Fix linter error in client_test package * Fix linter errors in coretypes package * Fix linter errors in coregrpc package * Fix linter errors in rpcserver package * Fix linter errors in rpctypes package * Fix linter errors in rpctest package * Fix linter error in json2wal script * Fix linter error in wal2json script * Fix linter errors in kv package * Fix linter error in state package * Fix linter error in grpc_client * Fix linter errors in types package * Fix linter error in version package * Fix remaining errors * Address review comments * Fix broken tests * Reconcile package coregrpc * Fix golangci bot error * Fix new golint errors * Fix broken reference * Enable golint linter * minor changes to bring golint into line * fix failing test * fix pex reactor naming * address PR comments
5 years ago
p2p: file descriptor leaks (#3150) * close peer's connection to avoid fd leak Fixes #2967 * rename peer#Addr to RemoteAddr * fix test * fixes after Ethan's review * bring back the check * changelog entry * write a test for switch#acceptRoutine * increase timeouts? :( * remove extra assertNPeersWithTimeout * simplify test * assert number of peers (just to be safe) * Cleanup in OnStop * run tests with verbose flag on CircleCI * spawn a reading routine to prevent connection from closing * get port from the listener random port is faster, but often results in ``` panic: listen tcp 127.0.0.1:44068: bind: address already in use [recovered] panic: listen tcp 127.0.0.1:44068: bind: address already in use goroutine 79 [running]: testing.tRunner.func1(0xc0001bd600) /usr/local/go/src/testing/testing.go:792 +0x387 panic(0x974d20, 0xc0001b0500) /usr/local/go/src/runtime/panic.go:513 +0x1b9 github.com/tendermint/tendermint/p2p.MakeSwitch(0xc0000f42a0, 0x0, 0x9fb9cc, 0x9, 0x9fc346, 0xb, 0xb42128, 0x0, 0x0, 0x0, ...) /home/vagrant/go/src/github.com/tendermint/tendermint/p2p/test_util.go:182 +0xa28 github.com/tendermint/tendermint/p2p.MakeConnectedSwitches(0xc0000f42a0, 0x2, 0xb42128, 0xb41eb8, 0x4f1205, 0xc0001bed80, 0x4f16ed) /home/vagrant/go/src/github.com/tendermint/tendermint/p2p/test_util.go:75 +0xf9 github.com/tendermint/tendermint/p2p.MakeSwitchPair(0xbb8d20, 0xc0001bd600, 0xb42128, 0x2f7, 0x4f16c0) /home/vagrant/go/src/github.com/tendermint/tendermint/p2p/switch_test.go:94 +0x4c github.com/tendermint/tendermint/p2p.TestSwitches(0xc0001bd600) /home/vagrant/go/src/github.com/tendermint/tendermint/p2p/switch_test.go:117 +0x58 testing.tRunner(0xc0001bd600, 0xb42038) /usr/local/go/src/testing/testing.go:827 +0xbf created by testing.(*T).Run /usr/local/go/src/testing/testing.go:878 +0x353 exit status 2 FAIL github.com/tendermint/tendermint/p2p 0.350s ```
6 years ago
p2p: file descriptor leaks (#3150) * close peer's connection to avoid fd leak Fixes #2967 * rename peer#Addr to RemoteAddr * fix test * fixes after Ethan's review * bring back the check * changelog entry * write a test for switch#acceptRoutine * increase timeouts? :( * remove extra assertNPeersWithTimeout * simplify test * assert number of peers (just to be safe) * Cleanup in OnStop * run tests with verbose flag on CircleCI * spawn a reading routine to prevent connection from closing * get port from the listener random port is faster, but often results in ``` panic: listen tcp 127.0.0.1:44068: bind: address already in use [recovered] panic: listen tcp 127.0.0.1:44068: bind: address already in use goroutine 79 [running]: testing.tRunner.func1(0xc0001bd600) /usr/local/go/src/testing/testing.go:792 +0x387 panic(0x974d20, 0xc0001b0500) /usr/local/go/src/runtime/panic.go:513 +0x1b9 github.com/tendermint/tendermint/p2p.MakeSwitch(0xc0000f42a0, 0x0, 0x9fb9cc, 0x9, 0x9fc346, 0xb, 0xb42128, 0x0, 0x0, 0x0, ...) /home/vagrant/go/src/github.com/tendermint/tendermint/p2p/test_util.go:182 +0xa28 github.com/tendermint/tendermint/p2p.MakeConnectedSwitches(0xc0000f42a0, 0x2, 0xb42128, 0xb41eb8, 0x4f1205, 0xc0001bed80, 0x4f16ed) /home/vagrant/go/src/github.com/tendermint/tendermint/p2p/test_util.go:75 +0xf9 github.com/tendermint/tendermint/p2p.MakeSwitchPair(0xbb8d20, 0xc0001bd600, 0xb42128, 0x2f7, 0x4f16c0) /home/vagrant/go/src/github.com/tendermint/tendermint/p2p/switch_test.go:94 +0x4c github.com/tendermint/tendermint/p2p.TestSwitches(0xc0001bd600) /home/vagrant/go/src/github.com/tendermint/tendermint/p2p/switch_test.go:117 +0x58 testing.tRunner(0xc0001bd600, 0xb42038) /usr/local/go/src/testing/testing.go:827 +0xbf created by testing.(*T).Run /usr/local/go/src/testing/testing.go:878 +0x353 exit status 2 FAIL github.com/tendermint/tendermint/p2p 0.350s ```
6 years ago
p2p: file descriptor leaks (#3150) * close peer's connection to avoid fd leak Fixes #2967 * rename peer#Addr to RemoteAddr * fix test * fixes after Ethan's review * bring back the check * changelog entry * write a test for switch#acceptRoutine * increase timeouts? :( * remove extra assertNPeersWithTimeout * simplify test * assert number of peers (just to be safe) * Cleanup in OnStop * run tests with verbose flag on CircleCI * spawn a reading routine to prevent connection from closing * get port from the listener random port is faster, but often results in ``` panic: listen tcp 127.0.0.1:44068: bind: address already in use [recovered] panic: listen tcp 127.0.0.1:44068: bind: address already in use goroutine 79 [running]: testing.tRunner.func1(0xc0001bd600) /usr/local/go/src/testing/testing.go:792 +0x387 panic(0x974d20, 0xc0001b0500) /usr/local/go/src/runtime/panic.go:513 +0x1b9 github.com/tendermint/tendermint/p2p.MakeSwitch(0xc0000f42a0, 0x0, 0x9fb9cc, 0x9, 0x9fc346, 0xb, 0xb42128, 0x0, 0x0, 0x0, ...) /home/vagrant/go/src/github.com/tendermint/tendermint/p2p/test_util.go:182 +0xa28 github.com/tendermint/tendermint/p2p.MakeConnectedSwitches(0xc0000f42a0, 0x2, 0xb42128, 0xb41eb8, 0x4f1205, 0xc0001bed80, 0x4f16ed) /home/vagrant/go/src/github.com/tendermint/tendermint/p2p/test_util.go:75 +0xf9 github.com/tendermint/tendermint/p2p.MakeSwitchPair(0xbb8d20, 0xc0001bd600, 0xb42128, 0x2f7, 0x4f16c0) /home/vagrant/go/src/github.com/tendermint/tendermint/p2p/switch_test.go:94 +0x4c github.com/tendermint/tendermint/p2p.TestSwitches(0xc0001bd600) /home/vagrant/go/src/github.com/tendermint/tendermint/p2p/switch_test.go:117 +0x58 testing.tRunner(0xc0001bd600, 0xb42038) /usr/local/go/src/testing/testing.go:827 +0xbf created by testing.(*T).Run /usr/local/go/src/testing/testing.go:878 +0x353 exit status 2 FAIL github.com/tendermint/tendermint/p2p 0.350s ```
6 years ago
p2p: file descriptor leaks (#3150) * close peer's connection to avoid fd leak Fixes #2967 * rename peer#Addr to RemoteAddr * fix test * fixes after Ethan's review * bring back the check * changelog entry * write a test for switch#acceptRoutine * increase timeouts? :( * remove extra assertNPeersWithTimeout * simplify test * assert number of peers (just to be safe) * Cleanup in OnStop * run tests with verbose flag on CircleCI * spawn a reading routine to prevent connection from closing * get port from the listener random port is faster, but often results in ``` panic: listen tcp 127.0.0.1:44068: bind: address already in use [recovered] panic: listen tcp 127.0.0.1:44068: bind: address already in use goroutine 79 [running]: testing.tRunner.func1(0xc0001bd600) /usr/local/go/src/testing/testing.go:792 +0x387 panic(0x974d20, 0xc0001b0500) /usr/local/go/src/runtime/panic.go:513 +0x1b9 github.com/tendermint/tendermint/p2p.MakeSwitch(0xc0000f42a0, 0x0, 0x9fb9cc, 0x9, 0x9fc346, 0xb, 0xb42128, 0x0, 0x0, 0x0, ...) /home/vagrant/go/src/github.com/tendermint/tendermint/p2p/test_util.go:182 +0xa28 github.com/tendermint/tendermint/p2p.MakeConnectedSwitches(0xc0000f42a0, 0x2, 0xb42128, 0xb41eb8, 0x4f1205, 0xc0001bed80, 0x4f16ed) /home/vagrant/go/src/github.com/tendermint/tendermint/p2p/test_util.go:75 +0xf9 github.com/tendermint/tendermint/p2p.MakeSwitchPair(0xbb8d20, 0xc0001bd600, 0xb42128, 0x2f7, 0x4f16c0) /home/vagrant/go/src/github.com/tendermint/tendermint/p2p/switch_test.go:94 +0x4c github.com/tendermint/tendermint/p2p.TestSwitches(0xc0001bd600) /home/vagrant/go/src/github.com/tendermint/tendermint/p2p/switch_test.go:117 +0x58 testing.tRunner(0xc0001bd600, 0xb42038) /usr/local/go/src/testing/testing.go:827 +0xbf created by testing.(*T).Run /usr/local/go/src/testing/testing.go:878 +0x353 exit status 2 FAIL github.com/tendermint/tendermint/p2p 0.350s ```
6 years ago
p2p: file descriptor leaks (#3150) * close peer's connection to avoid fd leak Fixes #2967 * rename peer#Addr to RemoteAddr * fix test * fixes after Ethan's review * bring back the check * changelog entry * write a test for switch#acceptRoutine * increase timeouts? :( * remove extra assertNPeersWithTimeout * simplify test * assert number of peers (just to be safe) * Cleanup in OnStop * run tests with verbose flag on CircleCI * spawn a reading routine to prevent connection from closing * get port from the listener random port is faster, but often results in ``` panic: listen tcp 127.0.0.1:44068: bind: address already in use [recovered] panic: listen tcp 127.0.0.1:44068: bind: address already in use goroutine 79 [running]: testing.tRunner.func1(0xc0001bd600) /usr/local/go/src/testing/testing.go:792 +0x387 panic(0x974d20, 0xc0001b0500) /usr/local/go/src/runtime/panic.go:513 +0x1b9 github.com/tendermint/tendermint/p2p.MakeSwitch(0xc0000f42a0, 0x0, 0x9fb9cc, 0x9, 0x9fc346, 0xb, 0xb42128, 0x0, 0x0, 0x0, ...) /home/vagrant/go/src/github.com/tendermint/tendermint/p2p/test_util.go:182 +0xa28 github.com/tendermint/tendermint/p2p.MakeConnectedSwitches(0xc0000f42a0, 0x2, 0xb42128, 0xb41eb8, 0x4f1205, 0xc0001bed80, 0x4f16ed) /home/vagrant/go/src/github.com/tendermint/tendermint/p2p/test_util.go:75 +0xf9 github.com/tendermint/tendermint/p2p.MakeSwitchPair(0xbb8d20, 0xc0001bd600, 0xb42128, 0x2f7, 0x4f16c0) /home/vagrant/go/src/github.com/tendermint/tendermint/p2p/switch_test.go:94 +0x4c github.com/tendermint/tendermint/p2p.TestSwitches(0xc0001bd600) /home/vagrant/go/src/github.com/tendermint/tendermint/p2p/switch_test.go:117 +0x58 testing.tRunner(0xc0001bd600, 0xb42038) /usr/local/go/src/testing/testing.go:827 +0xbf created by testing.(*T).Run /usr/local/go/src/testing/testing.go:878 +0x353 exit status 2 FAIL github.com/tendermint/tendermint/p2p 0.350s ```
6 years ago
p2p: file descriptor leaks (#3150) * close peer's connection to avoid fd leak Fixes #2967 * rename peer#Addr to RemoteAddr * fix test * fixes after Ethan's review * bring back the check * changelog entry * write a test for switch#acceptRoutine * increase timeouts? :( * remove extra assertNPeersWithTimeout * simplify test * assert number of peers (just to be safe) * Cleanup in OnStop * run tests with verbose flag on CircleCI * spawn a reading routine to prevent connection from closing * get port from the listener random port is faster, but often results in ``` panic: listen tcp 127.0.0.1:44068: bind: address already in use [recovered] panic: listen tcp 127.0.0.1:44068: bind: address already in use goroutine 79 [running]: testing.tRunner.func1(0xc0001bd600) /usr/local/go/src/testing/testing.go:792 +0x387 panic(0x974d20, 0xc0001b0500) /usr/local/go/src/runtime/panic.go:513 +0x1b9 github.com/tendermint/tendermint/p2p.MakeSwitch(0xc0000f42a0, 0x0, 0x9fb9cc, 0x9, 0x9fc346, 0xb, 0xb42128, 0x0, 0x0, 0x0, ...) /home/vagrant/go/src/github.com/tendermint/tendermint/p2p/test_util.go:182 +0xa28 github.com/tendermint/tendermint/p2p.MakeConnectedSwitches(0xc0000f42a0, 0x2, 0xb42128, 0xb41eb8, 0x4f1205, 0xc0001bed80, 0x4f16ed) /home/vagrant/go/src/github.com/tendermint/tendermint/p2p/test_util.go:75 +0xf9 github.com/tendermint/tendermint/p2p.MakeSwitchPair(0xbb8d20, 0xc0001bd600, 0xb42128, 0x2f7, 0x4f16c0) /home/vagrant/go/src/github.com/tendermint/tendermint/p2p/switch_test.go:94 +0x4c github.com/tendermint/tendermint/p2p.TestSwitches(0xc0001bd600) /home/vagrant/go/src/github.com/tendermint/tendermint/p2p/switch_test.go:117 +0x58 testing.tRunner(0xc0001bd600, 0xb42038) /usr/local/go/src/testing/testing.go:827 +0xbf created by testing.(*T).Run /usr/local/go/src/testing/testing.go:878 +0x353 exit status 2 FAIL github.com/tendermint/tendermint/p2p 0.350s ```
6 years ago
p2p: file descriptor leaks (#3150) * close peer's connection to avoid fd leak Fixes #2967 * rename peer#Addr to RemoteAddr * fix test * fixes after Ethan's review * bring back the check * changelog entry * write a test for switch#acceptRoutine * increase timeouts? :( * remove extra assertNPeersWithTimeout * simplify test * assert number of peers (just to be safe) * Cleanup in OnStop * run tests with verbose flag on CircleCI * spawn a reading routine to prevent connection from closing * get port from the listener random port is faster, but often results in ``` panic: listen tcp 127.0.0.1:44068: bind: address already in use [recovered] panic: listen tcp 127.0.0.1:44068: bind: address already in use goroutine 79 [running]: testing.tRunner.func1(0xc0001bd600) /usr/local/go/src/testing/testing.go:792 +0x387 panic(0x974d20, 0xc0001b0500) /usr/local/go/src/runtime/panic.go:513 +0x1b9 github.com/tendermint/tendermint/p2p.MakeSwitch(0xc0000f42a0, 0x0, 0x9fb9cc, 0x9, 0x9fc346, 0xb, 0xb42128, 0x0, 0x0, 0x0, ...) /home/vagrant/go/src/github.com/tendermint/tendermint/p2p/test_util.go:182 +0xa28 github.com/tendermint/tendermint/p2p.MakeConnectedSwitches(0xc0000f42a0, 0x2, 0xb42128, 0xb41eb8, 0x4f1205, 0xc0001bed80, 0x4f16ed) /home/vagrant/go/src/github.com/tendermint/tendermint/p2p/test_util.go:75 +0xf9 github.com/tendermint/tendermint/p2p.MakeSwitchPair(0xbb8d20, 0xc0001bd600, 0xb42128, 0x2f7, 0x4f16c0) /home/vagrant/go/src/github.com/tendermint/tendermint/p2p/switch_test.go:94 +0x4c github.com/tendermint/tendermint/p2p.TestSwitches(0xc0001bd600) /home/vagrant/go/src/github.com/tendermint/tendermint/p2p/switch_test.go:117 +0x58 testing.tRunner(0xc0001bd600, 0xb42038) /usr/local/go/src/testing/testing.go:827 +0xbf created by testing.(*T).Run /usr/local/go/src/testing/testing.go:878 +0x353 exit status 2 FAIL github.com/tendermint/tendermint/p2p 0.350s ```
6 years ago
p2p: file descriptor leaks (#3150) * close peer's connection to avoid fd leak Fixes #2967 * rename peer#Addr to RemoteAddr * fix test * fixes after Ethan's review * bring back the check * changelog entry * write a test for switch#acceptRoutine * increase timeouts? :( * remove extra assertNPeersWithTimeout * simplify test * assert number of peers (just to be safe) * Cleanup in OnStop * run tests with verbose flag on CircleCI * spawn a reading routine to prevent connection from closing * get port from the listener random port is faster, but often results in ``` panic: listen tcp 127.0.0.1:44068: bind: address already in use [recovered] panic: listen tcp 127.0.0.1:44068: bind: address already in use goroutine 79 [running]: testing.tRunner.func1(0xc0001bd600) /usr/local/go/src/testing/testing.go:792 +0x387 panic(0x974d20, 0xc0001b0500) /usr/local/go/src/runtime/panic.go:513 +0x1b9 github.com/tendermint/tendermint/p2p.MakeSwitch(0xc0000f42a0, 0x0, 0x9fb9cc, 0x9, 0x9fc346, 0xb, 0xb42128, 0x0, 0x0, 0x0, ...) /home/vagrant/go/src/github.com/tendermint/tendermint/p2p/test_util.go:182 +0xa28 github.com/tendermint/tendermint/p2p.MakeConnectedSwitches(0xc0000f42a0, 0x2, 0xb42128, 0xb41eb8, 0x4f1205, 0xc0001bed80, 0x4f16ed) /home/vagrant/go/src/github.com/tendermint/tendermint/p2p/test_util.go:75 +0xf9 github.com/tendermint/tendermint/p2p.MakeSwitchPair(0xbb8d20, 0xc0001bd600, 0xb42128, 0x2f7, 0x4f16c0) /home/vagrant/go/src/github.com/tendermint/tendermint/p2p/switch_test.go:94 +0x4c github.com/tendermint/tendermint/p2p.TestSwitches(0xc0001bd600) /home/vagrant/go/src/github.com/tendermint/tendermint/p2p/switch_test.go:117 +0x58 testing.tRunner(0xc0001bd600, 0xb42038) /usr/local/go/src/testing/testing.go:827 +0xbf created by testing.(*T).Run /usr/local/go/src/testing/testing.go:878 +0x353 exit status 2 FAIL github.com/tendermint/tendermint/p2p 0.350s ```
6 years ago
p2p: file descriptor leaks (#3150) * close peer's connection to avoid fd leak Fixes #2967 * rename peer#Addr to RemoteAddr * fix test * fixes after Ethan's review * bring back the check * changelog entry * write a test for switch#acceptRoutine * increase timeouts? :( * remove extra assertNPeersWithTimeout * simplify test * assert number of peers (just to be safe) * Cleanup in OnStop * run tests with verbose flag on CircleCI * spawn a reading routine to prevent connection from closing * get port from the listener random port is faster, but often results in ``` panic: listen tcp 127.0.0.1:44068: bind: address already in use [recovered] panic: listen tcp 127.0.0.1:44068: bind: address already in use goroutine 79 [running]: testing.tRunner.func1(0xc0001bd600) /usr/local/go/src/testing/testing.go:792 +0x387 panic(0x974d20, 0xc0001b0500) /usr/local/go/src/runtime/panic.go:513 +0x1b9 github.com/tendermint/tendermint/p2p.MakeSwitch(0xc0000f42a0, 0x0, 0x9fb9cc, 0x9, 0x9fc346, 0xb, 0xb42128, 0x0, 0x0, 0x0, ...) /home/vagrant/go/src/github.com/tendermint/tendermint/p2p/test_util.go:182 +0xa28 github.com/tendermint/tendermint/p2p.MakeConnectedSwitches(0xc0000f42a0, 0x2, 0xb42128, 0xb41eb8, 0x4f1205, 0xc0001bed80, 0x4f16ed) /home/vagrant/go/src/github.com/tendermint/tendermint/p2p/test_util.go:75 +0xf9 github.com/tendermint/tendermint/p2p.MakeSwitchPair(0xbb8d20, 0xc0001bd600, 0xb42128, 0x2f7, 0x4f16c0) /home/vagrant/go/src/github.com/tendermint/tendermint/p2p/switch_test.go:94 +0x4c github.com/tendermint/tendermint/p2p.TestSwitches(0xc0001bd600) /home/vagrant/go/src/github.com/tendermint/tendermint/p2p/switch_test.go:117 +0x58 testing.tRunner(0xc0001bd600, 0xb42038) /usr/local/go/src/testing/testing.go:827 +0xbf created by testing.(*T).Run /usr/local/go/src/testing/testing.go:878 +0x353 exit status 2 FAIL github.com/tendermint/tendermint/p2p 0.350s ```
6 years ago
p2p: file descriptor leaks (#3150) * close peer's connection to avoid fd leak Fixes #2967 * rename peer#Addr to RemoteAddr * fix test * fixes after Ethan's review * bring back the check * changelog entry * write a test for switch#acceptRoutine * increase timeouts? :( * remove extra assertNPeersWithTimeout * simplify test * assert number of peers (just to be safe) * Cleanup in OnStop * run tests with verbose flag on CircleCI * spawn a reading routine to prevent connection from closing * get port from the listener random port is faster, but often results in ``` panic: listen tcp 127.0.0.1:44068: bind: address already in use [recovered] panic: listen tcp 127.0.0.1:44068: bind: address already in use goroutine 79 [running]: testing.tRunner.func1(0xc0001bd600) /usr/local/go/src/testing/testing.go:792 +0x387 panic(0x974d20, 0xc0001b0500) /usr/local/go/src/runtime/panic.go:513 +0x1b9 github.com/tendermint/tendermint/p2p.MakeSwitch(0xc0000f42a0, 0x0, 0x9fb9cc, 0x9, 0x9fc346, 0xb, 0xb42128, 0x0, 0x0, 0x0, ...) /home/vagrant/go/src/github.com/tendermint/tendermint/p2p/test_util.go:182 +0xa28 github.com/tendermint/tendermint/p2p.MakeConnectedSwitches(0xc0000f42a0, 0x2, 0xb42128, 0xb41eb8, 0x4f1205, 0xc0001bed80, 0x4f16ed) /home/vagrant/go/src/github.com/tendermint/tendermint/p2p/test_util.go:75 +0xf9 github.com/tendermint/tendermint/p2p.MakeSwitchPair(0xbb8d20, 0xc0001bd600, 0xb42128, 0x2f7, 0x4f16c0) /home/vagrant/go/src/github.com/tendermint/tendermint/p2p/switch_test.go:94 +0x4c github.com/tendermint/tendermint/p2p.TestSwitches(0xc0001bd600) /home/vagrant/go/src/github.com/tendermint/tendermint/p2p/switch_test.go:117 +0x58 testing.tRunner(0xc0001bd600, 0xb42038) /usr/local/go/src/testing/testing.go:827 +0xbf created by testing.(*T).Run /usr/local/go/src/testing/testing.go:878 +0x353 exit status 2 FAIL github.com/tendermint/tendermint/p2p 0.350s ```
6 years ago
  1. package p2p
  2. import (
  3. "bytes"
  4. "errors"
  5. "fmt"
  6. "io"
  7. "io/ioutil"
  8. "net"
  9. "net/http"
  10. "net/http/httptest"
  11. "regexp"
  12. "strconv"
  13. "sync"
  14. "sync/atomic"
  15. "testing"
  16. "time"
  17. "github.com/prometheus/client_golang/prometheus/promhttp"
  18. "github.com/stretchr/testify/assert"
  19. "github.com/stretchr/testify/require"
  20. "github.com/tendermint/tendermint/config"
  21. "github.com/tendermint/tendermint/crypto/ed25519"
  22. "github.com/tendermint/tendermint/libs/log"
  23. "github.com/tendermint/tendermint/p2p/conn"
  24. )
  25. var (
  26. cfg *config.P2PConfig
  27. )
  28. func init() {
  29. cfg = config.DefaultP2PConfig()
  30. cfg.PexReactor = true
  31. cfg.AllowDuplicateIP = true
  32. }
  33. type PeerMessage struct {
  34. PeerID ID
  35. Bytes []byte
  36. Counter int
  37. }
  38. type TestReactor struct {
  39. BaseReactor
  40. mtx sync.Mutex
  41. channels []*conn.ChannelDescriptor
  42. logMessages bool
  43. msgsCounter int
  44. msgsReceived map[byte][]PeerMessage
  45. }
  46. func NewTestReactor(channels []*conn.ChannelDescriptor, logMessages bool) *TestReactor {
  47. tr := &TestReactor{
  48. channels: channels,
  49. logMessages: logMessages,
  50. msgsReceived: make(map[byte][]PeerMessage),
  51. }
  52. tr.BaseReactor = *NewBaseReactor("TestReactor", tr)
  53. tr.SetLogger(log.TestingLogger())
  54. return tr
  55. }
  56. func (tr *TestReactor) GetChannels() []*conn.ChannelDescriptor {
  57. return tr.channels
  58. }
  59. func (tr *TestReactor) AddPeer(peer Peer) {}
  60. func (tr *TestReactor) RemovePeer(peer Peer, reason interface{}) {}
  61. func (tr *TestReactor) Receive(chID byte, peer Peer, msgBytes []byte) {
  62. if tr.logMessages {
  63. tr.mtx.Lock()
  64. defer tr.mtx.Unlock()
  65. //fmt.Printf("Received: %X, %X\n", chID, msgBytes)
  66. tr.msgsReceived[chID] = append(tr.msgsReceived[chID], PeerMessage{peer.ID(), msgBytes, tr.msgsCounter})
  67. tr.msgsCounter++
  68. }
  69. }
  70. func (tr *TestReactor) getMsgs(chID byte) []PeerMessage {
  71. tr.mtx.Lock()
  72. defer tr.mtx.Unlock()
  73. return tr.msgsReceived[chID]
  74. }
  75. //-----------------------------------------------------------------------------
  76. // convenience method for creating two switches connected to each other.
  77. // XXX: note this uses net.Pipe and not a proper TCP conn
  78. func MakeSwitchPair(t testing.TB, initSwitch func(int, *Switch) *Switch) (*Switch, *Switch) {
  79. // Create two switches that will be interconnected.
  80. switches := MakeConnectedSwitches(cfg, 2, initSwitch, Connect2Switches)
  81. return switches[0], switches[1]
  82. }
  83. func initSwitchFunc(i int, sw *Switch) *Switch {
  84. sw.SetAddrBook(&addrBookMock{
  85. addrs: make(map[string]struct{}),
  86. ourAddrs: make(map[string]struct{})})
  87. // Make two reactors of two channels each
  88. sw.AddReactor("foo", NewTestReactor([]*conn.ChannelDescriptor{
  89. {ID: byte(0x00), Priority: 10},
  90. {ID: byte(0x01), Priority: 10},
  91. }, true))
  92. sw.AddReactor("bar", NewTestReactor([]*conn.ChannelDescriptor{
  93. {ID: byte(0x02), Priority: 10},
  94. {ID: byte(0x03), Priority: 10},
  95. }, true))
  96. return sw
  97. }
  98. func TestSwitches(t *testing.T) {
  99. s1, s2 := MakeSwitchPair(t, initSwitchFunc)
  100. defer s1.Stop()
  101. defer s2.Stop()
  102. if s1.Peers().Size() != 1 {
  103. t.Errorf("expected exactly 1 peer in s1, got %v", s1.Peers().Size())
  104. }
  105. if s2.Peers().Size() != 1 {
  106. t.Errorf("expected exactly 1 peer in s2, got %v", s2.Peers().Size())
  107. }
  108. // Lets send some messages
  109. ch0Msg := []byte("channel zero")
  110. ch1Msg := []byte("channel foo")
  111. ch2Msg := []byte("channel bar")
  112. s1.Broadcast(byte(0x00), ch0Msg)
  113. s1.Broadcast(byte(0x01), ch1Msg)
  114. s1.Broadcast(byte(0x02), ch2Msg)
  115. assertMsgReceivedWithTimeout(t,
  116. ch0Msg,
  117. byte(0x00),
  118. s2.Reactor("foo").(*TestReactor), 10*time.Millisecond, 5*time.Second)
  119. assertMsgReceivedWithTimeout(t,
  120. ch1Msg,
  121. byte(0x01),
  122. s2.Reactor("foo").(*TestReactor), 10*time.Millisecond, 5*time.Second)
  123. assertMsgReceivedWithTimeout(t,
  124. ch2Msg,
  125. byte(0x02),
  126. s2.Reactor("bar").(*TestReactor), 10*time.Millisecond, 5*time.Second)
  127. }
  128. func assertMsgReceivedWithTimeout(
  129. t *testing.T,
  130. msgBytes []byte,
  131. channel byte,
  132. reactor *TestReactor,
  133. checkPeriod,
  134. timeout time.Duration,
  135. ) {
  136. ticker := time.NewTicker(checkPeriod)
  137. for {
  138. select {
  139. case <-ticker.C:
  140. msgs := reactor.getMsgs(channel)
  141. if len(msgs) > 0 {
  142. if !bytes.Equal(msgs[0].Bytes, msgBytes) {
  143. t.Fatalf("Unexpected message bytes. Wanted: %X, Got: %X", msgBytes, msgs[0].Bytes)
  144. }
  145. return
  146. }
  147. case <-time.After(timeout):
  148. t.Fatalf("Expected to have received 1 message in channel #%v, got zero", channel)
  149. }
  150. }
  151. }
  152. func TestSwitchFiltersOutItself(t *testing.T) {
  153. s1 := MakeSwitch(cfg, 1, "127.0.0.1", "123.123.123", initSwitchFunc)
  154. // simulate s1 having a public IP by creating a remote peer with the same ID
  155. rp := &remotePeer{PrivKey: s1.nodeKey.PrivKey, Config: cfg}
  156. rp.Start()
  157. // addr should be rejected in addPeer based on the same ID
  158. err := s1.DialPeerWithAddress(rp.Addr())
  159. if assert.Error(t, err) {
  160. if err, ok := err.(ErrRejected); ok {
  161. if !err.IsSelf() {
  162. t.Errorf("expected self to be rejected")
  163. }
  164. } else {
  165. t.Errorf("expected ErrRejected")
  166. }
  167. }
  168. assert.True(t, s1.addrBook.OurAddress(rp.Addr()))
  169. assert.False(t, s1.addrBook.HasAddress(rp.Addr()))
  170. rp.Stop()
  171. assertNoPeersAfterTimeout(t, s1, 100*time.Millisecond)
  172. }
  173. func TestSwitchPeerFilter(t *testing.T) {
  174. var (
  175. filters = []PeerFilterFunc{
  176. func(_ IPeerSet, _ Peer) error { return nil },
  177. func(_ IPeerSet, _ Peer) error { return fmt.Errorf("denied") },
  178. func(_ IPeerSet, _ Peer) error { return nil },
  179. }
  180. sw = MakeSwitch(
  181. cfg,
  182. 1,
  183. "testing",
  184. "123.123.123",
  185. initSwitchFunc,
  186. SwitchPeerFilters(filters...),
  187. )
  188. )
  189. defer sw.Stop()
  190. // simulate remote peer
  191. rp := &remotePeer{PrivKey: ed25519.GenPrivKey(), Config: cfg}
  192. rp.Start()
  193. defer rp.Stop()
  194. p, err := sw.transport.Dial(*rp.Addr(), peerConfig{
  195. chDescs: sw.chDescs,
  196. onPeerError: sw.StopPeerForError,
  197. isPersistent: sw.IsPeerPersistent,
  198. reactorsByCh: sw.reactorsByCh,
  199. })
  200. if err != nil {
  201. t.Fatal(err)
  202. }
  203. err = sw.addPeer(p)
  204. if err, ok := err.(ErrRejected); ok {
  205. if !err.IsFiltered() {
  206. t.Errorf("expected peer to be filtered")
  207. }
  208. } else {
  209. t.Errorf("expected ErrRejected")
  210. }
  211. }
  212. func TestSwitchPeerFilterTimeout(t *testing.T) {
  213. var (
  214. filters = []PeerFilterFunc{
  215. func(_ IPeerSet, _ Peer) error {
  216. time.Sleep(10 * time.Millisecond)
  217. return nil
  218. },
  219. }
  220. sw = MakeSwitch(
  221. cfg,
  222. 1,
  223. "testing",
  224. "123.123.123",
  225. initSwitchFunc,
  226. SwitchFilterTimeout(5*time.Millisecond),
  227. SwitchPeerFilters(filters...),
  228. )
  229. )
  230. defer sw.Stop()
  231. // simulate remote peer
  232. rp := &remotePeer{PrivKey: ed25519.GenPrivKey(), Config: cfg}
  233. rp.Start()
  234. defer rp.Stop()
  235. p, err := sw.transport.Dial(*rp.Addr(), peerConfig{
  236. chDescs: sw.chDescs,
  237. onPeerError: sw.StopPeerForError,
  238. isPersistent: sw.IsPeerPersistent,
  239. reactorsByCh: sw.reactorsByCh,
  240. })
  241. if err != nil {
  242. t.Fatal(err)
  243. }
  244. err = sw.addPeer(p)
  245. if _, ok := err.(ErrFilterTimeout); !ok {
  246. t.Errorf("expected ErrFilterTimeout")
  247. }
  248. }
  249. func TestSwitchPeerFilterDuplicate(t *testing.T) {
  250. sw := MakeSwitch(cfg, 1, "testing", "123.123.123", initSwitchFunc)
  251. sw.Start()
  252. defer sw.Stop()
  253. // simulate remote peer
  254. rp := &remotePeer{PrivKey: ed25519.GenPrivKey(), Config: cfg}
  255. rp.Start()
  256. defer rp.Stop()
  257. p, err := sw.transport.Dial(*rp.Addr(), peerConfig{
  258. chDescs: sw.chDescs,
  259. onPeerError: sw.StopPeerForError,
  260. isPersistent: sw.IsPeerPersistent,
  261. reactorsByCh: sw.reactorsByCh,
  262. })
  263. if err != nil {
  264. t.Fatal(err)
  265. }
  266. if err := sw.addPeer(p); err != nil {
  267. t.Fatal(err)
  268. }
  269. err = sw.addPeer(p)
  270. if errRej, ok := err.(ErrRejected); ok {
  271. if !errRej.IsDuplicate() {
  272. t.Errorf("expected peer to be duplicate. got %v", errRej)
  273. }
  274. } else {
  275. t.Errorf("expected ErrRejected, got %v", err)
  276. }
  277. }
  278. func assertNoPeersAfterTimeout(t *testing.T, sw *Switch, timeout time.Duration) {
  279. time.Sleep(timeout)
  280. if sw.Peers().Size() != 0 {
  281. t.Fatalf("Expected %v to not connect to some peers, got %d", sw, sw.Peers().Size())
  282. }
  283. }
  284. func TestSwitchStopsNonPersistentPeerOnError(t *testing.T) {
  285. assert, require := assert.New(t), require.New(t)
  286. sw := MakeSwitch(cfg, 1, "testing", "123.123.123", initSwitchFunc)
  287. err := sw.Start()
  288. if err != nil {
  289. t.Error(err)
  290. }
  291. defer sw.Stop()
  292. // simulate remote peer
  293. rp := &remotePeer{PrivKey: ed25519.GenPrivKey(), Config: cfg}
  294. rp.Start()
  295. defer rp.Stop()
  296. p, err := sw.transport.Dial(*rp.Addr(), peerConfig{
  297. chDescs: sw.chDescs,
  298. onPeerError: sw.StopPeerForError,
  299. isPersistent: sw.IsPeerPersistent,
  300. reactorsByCh: sw.reactorsByCh,
  301. })
  302. require.Nil(err)
  303. err = sw.addPeer(p)
  304. require.Nil(err)
  305. require.NotNil(sw.Peers().Get(rp.ID()))
  306. // simulate failure by closing connection
  307. p.(*peer).CloseConn()
  308. assertNoPeersAfterTimeout(t, sw, 100*time.Millisecond)
  309. assert.False(p.IsRunning())
  310. }
  311. func TestSwitchStopPeerForError(t *testing.T) {
  312. s := httptest.NewServer(promhttp.Handler())
  313. defer s.Close()
  314. scrapeMetrics := func() string {
  315. resp, err := http.Get(s.URL)
  316. assert.NoError(t, err)
  317. defer resp.Body.Close()
  318. buf, _ := ioutil.ReadAll(resp.Body)
  319. return string(buf)
  320. }
  321. namespace, subsystem, name := config.TestInstrumentationConfig().Namespace, MetricsSubsystem, "peers"
  322. re := regexp.MustCompile(namespace + `_` + subsystem + `_` + name + ` ([0-9\.]+)`)
  323. peersMetricValue := func() float64 {
  324. matches := re.FindStringSubmatch(scrapeMetrics())
  325. f, _ := strconv.ParseFloat(matches[1], 64)
  326. return f
  327. }
  328. p2pMetrics := PrometheusMetrics(namespace)
  329. // make two connected switches
  330. sw1, sw2 := MakeSwitchPair(t, func(i int, sw *Switch) *Switch {
  331. // set metrics on sw1
  332. if i == 0 {
  333. opt := WithMetrics(p2pMetrics)
  334. opt(sw)
  335. }
  336. return initSwitchFunc(i, sw)
  337. })
  338. assert.Equal(t, len(sw1.Peers().List()), 1)
  339. assert.EqualValues(t, 1, peersMetricValue())
  340. // send messages to the peer from sw1
  341. p := sw1.Peers().List()[0]
  342. p.Send(0x1, []byte("here's a message to send"))
  343. // stop sw2. this should cause the p to fail,
  344. // which results in calling StopPeerForError internally
  345. sw2.Stop()
  346. // now call StopPeerForError explicitly, eg. from a reactor
  347. sw1.StopPeerForError(p, fmt.Errorf("some err"))
  348. assert.Equal(t, len(sw1.Peers().List()), 0)
  349. assert.EqualValues(t, 0, peersMetricValue())
  350. }
  351. func TestSwitchReconnectsToOutboundPersistentPeer(t *testing.T) {
  352. sw := MakeSwitch(cfg, 1, "testing", "123.123.123", initSwitchFunc)
  353. err := sw.Start()
  354. require.NoError(t, err)
  355. defer sw.Stop()
  356. // 1. simulate failure by closing connection
  357. rp := &remotePeer{PrivKey: ed25519.GenPrivKey(), Config: cfg}
  358. rp.Start()
  359. defer rp.Stop()
  360. err = sw.AddPersistentPeers([]string{rp.Addr().String()})
  361. require.NoError(t, err)
  362. err = sw.DialPeerWithAddress(rp.Addr())
  363. require.Nil(t, err)
  364. require.NotNil(t, sw.Peers().Get(rp.ID()))
  365. p := sw.Peers().List()[0]
  366. p.(*peer).CloseConn()
  367. waitUntilSwitchHasAtLeastNPeers(sw, 1)
  368. assert.False(t, p.IsRunning()) // old peer instance
  369. assert.Equal(t, 1, sw.Peers().Size()) // new peer instance
  370. // 2. simulate first time dial failure
  371. rp = &remotePeer{
  372. PrivKey: ed25519.GenPrivKey(),
  373. Config: cfg,
  374. // Use different interface to prevent duplicate IP filter, this will break
  375. // beyond two peers.
  376. listenAddr: "127.0.0.1:0",
  377. }
  378. rp.Start()
  379. defer rp.Stop()
  380. conf := config.DefaultP2PConfig()
  381. conf.TestDialFail = true // will trigger a reconnect
  382. err = sw.addOutboundPeerWithConfig(rp.Addr(), conf)
  383. require.NotNil(t, err)
  384. // DialPeerWithAddres - sw.peerConfig resets the dialer
  385. waitUntilSwitchHasAtLeastNPeers(sw, 2)
  386. assert.Equal(t, 2, sw.Peers().Size())
  387. }
  388. func TestSwitchReconnectsToInboundPersistentPeer(t *testing.T) {
  389. sw := MakeSwitch(cfg, 1, "testing", "123.123.123", initSwitchFunc)
  390. err := sw.Start()
  391. require.NoError(t, err)
  392. defer sw.Stop()
  393. // 1. simulate failure by closing the connection
  394. rp := &remotePeer{PrivKey: ed25519.GenPrivKey(), Config: cfg}
  395. rp.Start()
  396. defer rp.Stop()
  397. err = sw.AddPersistentPeers([]string{rp.Addr().String()})
  398. require.NoError(t, err)
  399. conn, err := rp.Dial(sw.NetAddress())
  400. require.NoError(t, err)
  401. time.Sleep(50 * time.Millisecond)
  402. require.NotNil(t, sw.Peers().Get(rp.ID()))
  403. conn.Close()
  404. waitUntilSwitchHasAtLeastNPeers(sw, 1)
  405. assert.Equal(t, 1, sw.Peers().Size())
  406. }
  407. func TestSwitchDialPeersAsync(t *testing.T) {
  408. if testing.Short() {
  409. return
  410. }
  411. sw := MakeSwitch(cfg, 1, "testing", "123.123.123", initSwitchFunc)
  412. err := sw.Start()
  413. require.NoError(t, err)
  414. defer sw.Stop()
  415. rp := &remotePeer{PrivKey: ed25519.GenPrivKey(), Config: cfg}
  416. rp.Start()
  417. defer rp.Stop()
  418. err = sw.DialPeersAsync([]string{rp.Addr().String()})
  419. require.NoError(t, err)
  420. time.Sleep(dialRandomizerIntervalMilliseconds * time.Millisecond)
  421. require.NotNil(t, sw.Peers().Get(rp.ID()))
  422. }
  423. func waitUntilSwitchHasAtLeastNPeers(sw *Switch, n int) {
  424. for i := 0; i < 20; i++ {
  425. time.Sleep(250 * time.Millisecond)
  426. has := sw.Peers().Size()
  427. if has >= n {
  428. break
  429. }
  430. }
  431. }
  432. func TestSwitchFullConnectivity(t *testing.T) {
  433. switches := MakeConnectedSwitches(cfg, 3, initSwitchFunc, Connect2Switches)
  434. defer func() {
  435. for _, sw := range switches {
  436. sw.Stop()
  437. }
  438. }()
  439. for i, sw := range switches {
  440. if sw.Peers().Size() != 2 {
  441. t.Fatalf("Expected each switch to be connected to 2 other, but %d switch only connected to %d", sw.Peers().Size(), i)
  442. }
  443. }
  444. }
  445. func TestSwitchAcceptRoutine(t *testing.T) {
  446. cfg.MaxNumInboundPeers = 5
  447. // Create some unconditional peers.
  448. const unconditionalPeersNum = 2
  449. var (
  450. unconditionalPeers = make([]*remotePeer, unconditionalPeersNum)
  451. unconditionalPeerIDs = make([]string, unconditionalPeersNum)
  452. )
  453. for i := 0; i < unconditionalPeersNum; i++ {
  454. peer := &remotePeer{PrivKey: ed25519.GenPrivKey(), Config: cfg}
  455. peer.Start()
  456. unconditionalPeers[i] = peer
  457. unconditionalPeerIDs[i] = string(peer.ID())
  458. }
  459. // make switch
  460. sw := MakeSwitch(cfg, 1, "testing", "123.123.123", initSwitchFunc)
  461. sw.AddUnconditionalPeerIDs(unconditionalPeerIDs)
  462. err := sw.Start()
  463. require.NoError(t, err)
  464. defer sw.Stop()
  465. // 0. check there are no peers
  466. assert.Equal(t, 0, sw.Peers().Size())
  467. // 1. check we connect up to MaxNumInboundPeers
  468. peers := make([]*remotePeer, 0)
  469. for i := 0; i < cfg.MaxNumInboundPeers; i++ {
  470. peer := &remotePeer{PrivKey: ed25519.GenPrivKey(), Config: cfg}
  471. peers = append(peers, peer)
  472. peer.Start()
  473. c, err := peer.Dial(sw.NetAddress())
  474. require.NoError(t, err)
  475. // spawn a reading routine to prevent connection from closing
  476. go func(c net.Conn) {
  477. for {
  478. one := make([]byte, 1)
  479. _, err := c.Read(one)
  480. if err != nil {
  481. return
  482. }
  483. }
  484. }(c)
  485. }
  486. time.Sleep(10 * time.Millisecond)
  487. assert.Equal(t, cfg.MaxNumInboundPeers, sw.Peers().Size())
  488. // 2. check we close new connections if we already have MaxNumInboundPeers peers
  489. peer := &remotePeer{PrivKey: ed25519.GenPrivKey(), Config: cfg}
  490. peer.Start()
  491. conn, err := peer.Dial(sw.NetAddress())
  492. require.NoError(t, err)
  493. // check conn is closed
  494. one := make([]byte, 1)
  495. conn.SetReadDeadline(time.Now().Add(10 * time.Millisecond))
  496. _, err = conn.Read(one)
  497. assert.Equal(t, io.EOF, err)
  498. assert.Equal(t, cfg.MaxNumInboundPeers, sw.Peers().Size())
  499. peer.Stop()
  500. // 3. check we connect to unconditional peers despite the limit.
  501. for _, peer := range unconditionalPeers {
  502. c, err := peer.Dial(sw.NetAddress())
  503. require.NoError(t, err)
  504. // spawn a reading routine to prevent connection from closing
  505. go func(c net.Conn) {
  506. for {
  507. one := make([]byte, 1)
  508. _, err := c.Read(one)
  509. if err != nil {
  510. return
  511. }
  512. }
  513. }(c)
  514. }
  515. time.Sleep(10 * time.Millisecond)
  516. assert.Equal(t, cfg.MaxNumInboundPeers+unconditionalPeersNum, sw.Peers().Size())
  517. for _, peer := range peers {
  518. peer.Stop()
  519. }
  520. for _, peer := range unconditionalPeers {
  521. peer.Stop()
  522. }
  523. }
  524. type errorTransport struct {
  525. acceptErr error
  526. }
  527. func (et errorTransport) NetAddress() NetAddress {
  528. panic("not implemented")
  529. }
  530. func (et errorTransport) Accept(c peerConfig) (Peer, error) {
  531. return nil, et.acceptErr
  532. }
  533. func (errorTransport) Dial(NetAddress, peerConfig) (Peer, error) {
  534. panic("not implemented")
  535. }
  536. func (errorTransport) Cleanup(Peer) {
  537. panic("not implemented")
  538. }
  539. func TestSwitchAcceptRoutineErrorCases(t *testing.T) {
  540. sw := NewSwitch(cfg, errorTransport{ErrFilterTimeout{}})
  541. assert.NotPanics(t, func() {
  542. err := sw.Start()
  543. assert.NoError(t, err)
  544. sw.Stop()
  545. })
  546. sw = NewSwitch(cfg, errorTransport{ErrRejected{conn: nil, err: errors.New("filtered"), isFiltered: true}})
  547. assert.NotPanics(t, func() {
  548. err := sw.Start()
  549. assert.NoError(t, err)
  550. sw.Stop()
  551. })
  552. // TODO(melekes) check we remove our address from addrBook
  553. sw = NewSwitch(cfg, errorTransport{ErrTransportClosed{}})
  554. assert.NotPanics(t, func() {
  555. err := sw.Start()
  556. assert.NoError(t, err)
  557. sw.Stop()
  558. })
  559. }
  560. // mockReactor checks that InitPeer never called before RemovePeer. If that's
  561. // not true, InitCalledBeforeRemoveFinished will return true.
  562. type mockReactor struct {
  563. *BaseReactor
  564. // atomic
  565. removePeerInProgress uint32
  566. initCalledBeforeRemoveFinished uint32
  567. }
  568. func (r *mockReactor) RemovePeer(peer Peer, reason interface{}) {
  569. atomic.StoreUint32(&r.removePeerInProgress, 1)
  570. defer atomic.StoreUint32(&r.removePeerInProgress, 0)
  571. time.Sleep(100 * time.Millisecond)
  572. }
  573. func (r *mockReactor) InitPeer(peer Peer) Peer {
  574. if atomic.LoadUint32(&r.removePeerInProgress) == 1 {
  575. atomic.StoreUint32(&r.initCalledBeforeRemoveFinished, 1)
  576. }
  577. return peer
  578. }
  579. func (r *mockReactor) InitCalledBeforeRemoveFinished() bool {
  580. return atomic.LoadUint32(&r.initCalledBeforeRemoveFinished) == 1
  581. }
  582. // see stopAndRemovePeer
  583. func TestSwitchInitPeerIsNotCalledBeforeRemovePeer(t *testing.T) {
  584. // make reactor
  585. reactor := &mockReactor{}
  586. reactor.BaseReactor = NewBaseReactor("mockReactor", reactor)
  587. // make switch
  588. sw := MakeSwitch(cfg, 1, "testing", "123.123.123", func(i int, sw *Switch) *Switch {
  589. sw.AddReactor("mock", reactor)
  590. return sw
  591. })
  592. err := sw.Start()
  593. require.NoError(t, err)
  594. defer sw.Stop()
  595. // add peer
  596. rp := &remotePeer{PrivKey: ed25519.GenPrivKey(), Config: cfg}
  597. rp.Start()
  598. defer rp.Stop()
  599. _, err = rp.Dial(sw.NetAddress())
  600. require.NoError(t, err)
  601. // wait till the switch adds rp to the peer set
  602. time.Sleep(50 * time.Millisecond)
  603. // stop peer asynchronously
  604. go sw.StopPeerForError(sw.Peers().Get(rp.ID()), "test")
  605. // simulate peer reconnecting to us
  606. _, err = rp.Dial(sw.NetAddress())
  607. require.NoError(t, err)
  608. // wait till the switch adds rp to the peer set
  609. time.Sleep(50 * time.Millisecond)
  610. // make sure reactor.RemovePeer is finished before InitPeer is called
  611. assert.False(t, reactor.InitCalledBeforeRemoveFinished())
  612. }
  613. func BenchmarkSwitchBroadcast(b *testing.B) {
  614. s1, s2 := MakeSwitchPair(b, func(i int, sw *Switch) *Switch {
  615. // Make bar reactors of bar channels each
  616. sw.AddReactor("foo", NewTestReactor([]*conn.ChannelDescriptor{
  617. {ID: byte(0x00), Priority: 10},
  618. {ID: byte(0x01), Priority: 10},
  619. }, false))
  620. sw.AddReactor("bar", NewTestReactor([]*conn.ChannelDescriptor{
  621. {ID: byte(0x02), Priority: 10},
  622. {ID: byte(0x03), Priority: 10},
  623. }, false))
  624. return sw
  625. })
  626. defer s1.Stop()
  627. defer s2.Stop()
  628. // Allow time for goroutines to boot up
  629. time.Sleep(1 * time.Second)
  630. b.ResetTimer()
  631. numSuccess, numFailure := 0, 0
  632. // Send random message from foo channel to another
  633. for i := 0; i < b.N; i++ {
  634. chID := byte(i % 4)
  635. successChan := s1.Broadcast(chID, []byte("test data"))
  636. for s := range successChan {
  637. if s {
  638. numSuccess++
  639. } else {
  640. numFailure++
  641. }
  642. }
  643. }
  644. b.Logf("success: %v, failure: %v", numSuccess, numFailure)
  645. }
  646. type addrBookMock struct {
  647. addrs map[string]struct{}
  648. ourAddrs map[string]struct{}
  649. }
  650. var _ AddrBook = (*addrBookMock)(nil)
  651. func (book *addrBookMock) AddAddress(addr *NetAddress, src *NetAddress) error {
  652. book.addrs[addr.String()] = struct{}{}
  653. return nil
  654. }
  655. func (book *addrBookMock) AddOurAddress(addr *NetAddress) { book.ourAddrs[addr.String()] = struct{}{} }
  656. func (book *addrBookMock) OurAddress(addr *NetAddress) bool {
  657. _, ok := book.ourAddrs[addr.String()]
  658. return ok
  659. }
  660. func (book *addrBookMock) MarkGood(ID) {}
  661. func (book *addrBookMock) HasAddress(addr *NetAddress) bool {
  662. _, ok := book.addrs[addr.String()]
  663. return ok
  664. }
  665. func (book *addrBookMock) RemoveAddress(addr *NetAddress) {
  666. delete(book.addrs, addr.String())
  667. }
  668. func (book *addrBookMock) Save() {}