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.

870 lines
21 KiB

p2p: implement new Transport interface (#5791) This implements a new `Transport` interface and related types for the P2P refactor in #5670. Previously, `conn.MConnection` was very tightly coupled to the `Peer` implementation -- in order to allow alternative non-multiplexed transports (e.g. QUIC), MConnection has now been moved below the `Transport` interface, as `MConnTransport`, and decoupled from the peer. Since the `p2p` package is not covered by our Go API stability, this is not considered a breaking change, and not listed in the changelog. The initial approach was to implement the new interface in its final form (which also involved possible protocol changes, see https://github.com/tendermint/spec/pull/227). However, it turned out that this would require a large amount of changes to existing P2P code because of the previous tight coupling between `Peer` and `MConnection` and the reliance on subtleties in the MConnection behavior. Instead, I have broadened the `Transport` interface to expose much of the existing MConnection interface, preserved much of the existing MConnection logic and behavior in the transport implementation, and tried to make as few changes to the rest of the P2P stack as possible. We will instead reduce this interface gradually as we refactor other parts of the P2P stack. The low-level transport code and protocol (e.g. MConnection, SecretConnection and so on) has not been significantly changed, and refactoring this is not a priority until we come up with a plan for QUIC adoption, as we may end up discarding the MConnection code entirely. There are no tests of the new `MConnTransport`, as this code is likely to evolve as we proceed with the P2P refactor, but tests should be added before a final release. The E2E tests are sufficient for basic validation in the meanwhile.
4 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: implement new Transport interface (#5791) This implements a new `Transport` interface and related types for the P2P refactor in #5670. Previously, `conn.MConnection` was very tightly coupled to the `Peer` implementation -- in order to allow alternative non-multiplexed transports (e.g. QUIC), MConnection has now been moved below the `Transport` interface, as `MConnTransport`, and decoupled from the peer. Since the `p2p` package is not covered by our Go API stability, this is not considered a breaking change, and not listed in the changelog. The initial approach was to implement the new interface in its final form (which also involved possible protocol changes, see https://github.com/tendermint/spec/pull/227). However, it turned out that this would require a large amount of changes to existing P2P code because of the previous tight coupling between `Peer` and `MConnection` and the reliance on subtleties in the MConnection behavior. Instead, I have broadened the `Transport` interface to expose much of the existing MConnection interface, preserved much of the existing MConnection logic and behavior in the transport implementation, and tried to make as few changes to the rest of the P2P stack as possible. We will instead reduce this interface gradually as we refactor other parts of the P2P stack. The low-level transport code and protocol (e.g. MConnection, SecretConnection and so on) has not been significantly changed, and refactoring this is not a priority until we come up with a plan for QUIC adoption, as we may end up discarding the MConnection code entirely. There are no tests of the new `MConnTransport`, as this code is likely to evolve as we proceed with the P2P refactor, but tests should be added before a final release. The E2E tests are sufficient for basic validation in the meanwhile.
4 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: implement new Transport interface (#5791) This implements a new `Transport` interface and related types for the P2P refactor in #5670. Previously, `conn.MConnection` was very tightly coupled to the `Peer` implementation -- in order to allow alternative non-multiplexed transports (e.g. QUIC), MConnection has now been moved below the `Transport` interface, as `MConnTransport`, and decoupled from the peer. Since the `p2p` package is not covered by our Go API stability, this is not considered a breaking change, and not listed in the changelog. The initial approach was to implement the new interface in its final form (which also involved possible protocol changes, see https://github.com/tendermint/spec/pull/227). However, it turned out that this would require a large amount of changes to existing P2P code because of the previous tight coupling between `Peer` and `MConnection` and the reliance on subtleties in the MConnection behavior. Instead, I have broadened the `Transport` interface to expose much of the existing MConnection interface, preserved much of the existing MConnection logic and behavior in the transport implementation, and tried to make as few changes to the rest of the P2P stack as possible. We will instead reduce this interface gradually as we refactor other parts of the P2P stack. The low-level transport code and protocol (e.g. MConnection, SecretConnection and so on) has not been significantly changed, and refactoring this is not a priority until we come up with a plan for QUIC adoption, as we may end up discarding the MConnection code entirely. There are no tests of the new `MConnTransport`, as this code is likely to evolve as we proceed with the P2P refactor, but tests should be added before a final release. The E2E tests are sufficient for basic validation in the meanwhile.
4 years ago
p2p: implement new Transport interface (#5791) This implements a new `Transport` interface and related types for the P2P refactor in #5670. Previously, `conn.MConnection` was very tightly coupled to the `Peer` implementation -- in order to allow alternative non-multiplexed transports (e.g. QUIC), MConnection has now been moved below the `Transport` interface, as `MConnTransport`, and decoupled from the peer. Since the `p2p` package is not covered by our Go API stability, this is not considered a breaking change, and not listed in the changelog. The initial approach was to implement the new interface in its final form (which also involved possible protocol changes, see https://github.com/tendermint/spec/pull/227). However, it turned out that this would require a large amount of changes to existing P2P code because of the previous tight coupling between `Peer` and `MConnection` and the reliance on subtleties in the MConnection behavior. Instead, I have broadened the `Transport` interface to expose much of the existing MConnection interface, preserved much of the existing MConnection logic and behavior in the transport implementation, and tried to make as few changes to the rest of the P2P stack as possible. We will instead reduce this interface gradually as we refactor other parts of the P2P stack. The low-level transport code and protocol (e.g. MConnection, SecretConnection and so on) has not been significantly changed, and refactoring this is not a priority until we come up with a plan for QUIC adoption, as we may end up discarding the MConnection code entirely. There are no tests of the new `MConnTransport`, as this code is likely to evolve as we proceed with the P2P refactor, but tests should be added before a final release. The E2E tests are sufficient for basic validation in the meanwhile.
4 years ago
p2p: implement new Transport interface (#5791) This implements a new `Transport` interface and related types for the P2P refactor in #5670. Previously, `conn.MConnection` was very tightly coupled to the `Peer` implementation -- in order to allow alternative non-multiplexed transports (e.g. QUIC), MConnection has now been moved below the `Transport` interface, as `MConnTransport`, and decoupled from the peer. Since the `p2p` package is not covered by our Go API stability, this is not considered a breaking change, and not listed in the changelog. The initial approach was to implement the new interface in its final form (which also involved possible protocol changes, see https://github.com/tendermint/spec/pull/227). However, it turned out that this would require a large amount of changes to existing P2P code because of the previous tight coupling between `Peer` and `MConnection` and the reliance on subtleties in the MConnection behavior. Instead, I have broadened the `Transport` interface to expose much of the existing MConnection interface, preserved much of the existing MConnection logic and behavior in the transport implementation, and tried to make as few changes to the rest of the P2P stack as possible. We will instead reduce this interface gradually as we refactor other parts of the P2P stack. The low-level transport code and protocol (e.g. MConnection, SecretConnection and so on) has not been significantly changed, and refactoring this is not a priority until we come up with a plan for QUIC adoption, as we may end up discarding the MConnection code entirely. There are no tests of the new `MConnTransport`, as this code is likely to evolve as we proceed with the P2P refactor, but tests should be added before a final release. The E2E tests are sufficient for basic validation in the meanwhile.
4 years ago
p2p: implement new Transport interface (#5791) This implements a new `Transport` interface and related types for the P2P refactor in #5670. Previously, `conn.MConnection` was very tightly coupled to the `Peer` implementation -- in order to allow alternative non-multiplexed transports (e.g. QUIC), MConnection has now been moved below the `Transport` interface, as `MConnTransport`, and decoupled from the peer. Since the `p2p` package is not covered by our Go API stability, this is not considered a breaking change, and not listed in the changelog. The initial approach was to implement the new interface in its final form (which also involved possible protocol changes, see https://github.com/tendermint/spec/pull/227). However, it turned out that this would require a large amount of changes to existing P2P code because of the previous tight coupling between `Peer` and `MConnection` and the reliance on subtleties in the MConnection behavior. Instead, I have broadened the `Transport` interface to expose much of the existing MConnection interface, preserved much of the existing MConnection logic and behavior in the transport implementation, and tried to make as few changes to the rest of the P2P stack as possible. We will instead reduce this interface gradually as we refactor other parts of the P2P stack. The low-level transport code and protocol (e.g. MConnection, SecretConnection and so on) has not been significantly changed, and refactoring this is not a priority until we come up with a plan for QUIC adoption, as we may end up discarding the MConnection code entirely. There are no tests of the new `MConnTransport`, as this code is likely to evolve as we proceed with the P2P refactor, but tests should be added before a final release. The E2E tests are sufficient for basic validation in the meanwhile.
4 years ago
p2p: implement new Transport interface (#5791) This implements a new `Transport` interface and related types for the P2P refactor in #5670. Previously, `conn.MConnection` was very tightly coupled to the `Peer` implementation -- in order to allow alternative non-multiplexed transports (e.g. QUIC), MConnection has now been moved below the `Transport` interface, as `MConnTransport`, and decoupled from the peer. Since the `p2p` package is not covered by our Go API stability, this is not considered a breaking change, and not listed in the changelog. The initial approach was to implement the new interface in its final form (which also involved possible protocol changes, see https://github.com/tendermint/spec/pull/227). However, it turned out that this would require a large amount of changes to existing P2P code because of the previous tight coupling between `Peer` and `MConnection` and the reliance on subtleties in the MConnection behavior. Instead, I have broadened the `Transport` interface to expose much of the existing MConnection interface, preserved much of the existing MConnection logic and behavior in the transport implementation, and tried to make as few changes to the rest of the P2P stack as possible. We will instead reduce this interface gradually as we refactor other parts of the P2P stack. The low-level transport code and protocol (e.g. MConnection, SecretConnection and so on) has not been significantly changed, and refactoring this is not a priority until we come up with a plan for QUIC adoption, as we may end up discarding the MConnection code entirely. There are no tests of the new `MConnTransport`, as this code is likely to evolve as we proceed with the P2P refactor, but tests should be added before a final release. The E2E tests are sufficient for basic validation in the meanwhile.
4 years ago
p2p: implement new Transport interface (#5791) This implements a new `Transport` interface and related types for the P2P refactor in #5670. Previously, `conn.MConnection` was very tightly coupled to the `Peer` implementation -- in order to allow alternative non-multiplexed transports (e.g. QUIC), MConnection has now been moved below the `Transport` interface, as `MConnTransport`, and decoupled from the peer. Since the `p2p` package is not covered by our Go API stability, this is not considered a breaking change, and not listed in the changelog. The initial approach was to implement the new interface in its final form (which also involved possible protocol changes, see https://github.com/tendermint/spec/pull/227). However, it turned out that this would require a large amount of changes to existing P2P code because of the previous tight coupling between `Peer` and `MConnection` and the reliance on subtleties in the MConnection behavior. Instead, I have broadened the `Transport` interface to expose much of the existing MConnection interface, preserved much of the existing MConnection logic and behavior in the transport implementation, and tried to make as few changes to the rest of the P2P stack as possible. We will instead reduce this interface gradually as we refactor other parts of the P2P stack. The low-level transport code and protocol (e.g. MConnection, SecretConnection and so on) has not been significantly changed, and refactoring this is not a priority until we come up with a plan for QUIC adoption, as we may end up discarding the MConnection code entirely. There are no tests of the new `MConnTransport`, as this code is likely to evolve as we proceed with the P2P refactor, but tests should be added before a final release. The E2E tests are sufficient for basic validation in the meanwhile.
4 years ago
p2p: implement new Transport interface (#5791) This implements a new `Transport` interface and related types for the P2P refactor in #5670. Previously, `conn.MConnection` was very tightly coupled to the `Peer` implementation -- in order to allow alternative non-multiplexed transports (e.g. QUIC), MConnection has now been moved below the `Transport` interface, as `MConnTransport`, and decoupled from the peer. Since the `p2p` package is not covered by our Go API stability, this is not considered a breaking change, and not listed in the changelog. The initial approach was to implement the new interface in its final form (which also involved possible protocol changes, see https://github.com/tendermint/spec/pull/227). However, it turned out that this would require a large amount of changes to existing P2P code because of the previous tight coupling between `Peer` and `MConnection` and the reliance on subtleties in the MConnection behavior. Instead, I have broadened the `Transport` interface to expose much of the existing MConnection interface, preserved much of the existing MConnection logic and behavior in the transport implementation, and tried to make as few changes to the rest of the P2P stack as possible. We will instead reduce this interface gradually as we refactor other parts of the P2P stack. The low-level transport code and protocol (e.g. MConnection, SecretConnection and so on) has not been significantly changed, and refactoring this is not a priority until we come up with a plan for QUIC adoption, as we may end up discarding the MConnection code entirely. There are no tests of the new `MConnTransport`, as this code is likely to evolve as we proceed with the P2P refactor, but tests should be added before a final release. The E2E tests are sufficient for basic validation in the meanwhile.
4 years ago
p2p: implement new Transport interface (#5791) This implements a new `Transport` interface and related types for the P2P refactor in #5670. Previously, `conn.MConnection` was very tightly coupled to the `Peer` implementation -- in order to allow alternative non-multiplexed transports (e.g. QUIC), MConnection has now been moved below the `Transport` interface, as `MConnTransport`, and decoupled from the peer. Since the `p2p` package is not covered by our Go API stability, this is not considered a breaking change, and not listed in the changelog. The initial approach was to implement the new interface in its final form (which also involved possible protocol changes, see https://github.com/tendermint/spec/pull/227). However, it turned out that this would require a large amount of changes to existing P2P code because of the previous tight coupling between `Peer` and `MConnection` and the reliance on subtleties in the MConnection behavior. Instead, I have broadened the `Transport` interface to expose much of the existing MConnection interface, preserved much of the existing MConnection logic and behavior in the transport implementation, and tried to make as few changes to the rest of the P2P stack as possible. We will instead reduce this interface gradually as we refactor other parts of the P2P stack. The low-level transport code and protocol (e.g. MConnection, SecretConnection and so on) has not been significantly changed, and refactoring this is not a priority until we come up with a plan for QUIC adoption, as we may end up discarding the MConnection code entirely. There are no tests of the new `MConnTransport`, as this code is likely to evolve as we proceed with the P2P refactor, but tests should be added before a final release. The E2E tests are sufficient for basic validation in the meanwhile.
4 years ago
p2p: implement new Transport interface (#5791) This implements a new `Transport` interface and related types for the P2P refactor in #5670. Previously, `conn.MConnection` was very tightly coupled to the `Peer` implementation -- in order to allow alternative non-multiplexed transports (e.g. QUIC), MConnection has now been moved below the `Transport` interface, as `MConnTransport`, and decoupled from the peer. Since the `p2p` package is not covered by our Go API stability, this is not considered a breaking change, and not listed in the changelog. The initial approach was to implement the new interface in its final form (which also involved possible protocol changes, see https://github.com/tendermint/spec/pull/227). However, it turned out that this would require a large amount of changes to existing P2P code because of the previous tight coupling between `Peer` and `MConnection` and the reliance on subtleties in the MConnection behavior. Instead, I have broadened the `Transport` interface to expose much of the existing MConnection interface, preserved much of the existing MConnection logic and behavior in the transport implementation, and tried to make as few changes to the rest of the P2P stack as possible. We will instead reduce this interface gradually as we refactor other parts of the P2P stack. The low-level transport code and protocol (e.g. MConnection, SecretConnection and so on) has not been significantly changed, and refactoring this is not a priority until we come up with a plan for QUIC adoption, as we may end up discarding the MConnection code entirely. There are no tests of the new `MConnTransport`, as this code is likely to evolve as we proceed with the P2P refactor, but tests should be added before a final release. The E2E tests are sufficient for basic validation in the meanwhile.
4 years ago
p2p: implement new Transport interface (#5791) This implements a new `Transport` interface and related types for the P2P refactor in #5670. Previously, `conn.MConnection` was very tightly coupled to the `Peer` implementation -- in order to allow alternative non-multiplexed transports (e.g. QUIC), MConnection has now been moved below the `Transport` interface, as `MConnTransport`, and decoupled from the peer. Since the `p2p` package is not covered by our Go API stability, this is not considered a breaking change, and not listed in the changelog. The initial approach was to implement the new interface in its final form (which also involved possible protocol changes, see https://github.com/tendermint/spec/pull/227). However, it turned out that this would require a large amount of changes to existing P2P code because of the previous tight coupling between `Peer` and `MConnection` and the reliance on subtleties in the MConnection behavior. Instead, I have broadened the `Transport` interface to expose much of the existing MConnection interface, preserved much of the existing MConnection logic and behavior in the transport implementation, and tried to make as few changes to the rest of the P2P stack as possible. We will instead reduce this interface gradually as we refactor other parts of the P2P stack. The low-level transport code and protocol (e.g. MConnection, SecretConnection and so on) has not been significantly changed, and refactoring this is not a priority until we come up with a plan for QUIC adoption, as we may end up discarding the MConnection code entirely. There are no tests of the new `MConnTransport`, as this code is likely to evolve as we proceed with the P2P refactor, but tests should be added before a final release. The E2E tests are sufficient for basic validation in the meanwhile.
4 years ago
p2p: implement new Transport interface (#5791) This implements a new `Transport` interface and related types for the P2P refactor in #5670. Previously, `conn.MConnection` was very tightly coupled to the `Peer` implementation -- in order to allow alternative non-multiplexed transports (e.g. QUIC), MConnection has now been moved below the `Transport` interface, as `MConnTransport`, and decoupled from the peer. Since the `p2p` package is not covered by our Go API stability, this is not considered a breaking change, and not listed in the changelog. The initial approach was to implement the new interface in its final form (which also involved possible protocol changes, see https://github.com/tendermint/spec/pull/227). However, it turned out that this would require a large amount of changes to existing P2P code because of the previous tight coupling between `Peer` and `MConnection` and the reliance on subtleties in the MConnection behavior. Instead, I have broadened the `Transport` interface to expose much of the existing MConnection interface, preserved much of the existing MConnection logic and behavior in the transport implementation, and tried to make as few changes to the rest of the P2P stack as possible. We will instead reduce this interface gradually as we refactor other parts of the P2P stack. The low-level transport code and protocol (e.g. MConnection, SecretConnection and so on) has not been significantly changed, and refactoring this is not a priority until we come up with a plan for QUIC adoption, as we may end up discarding the MConnection code entirely. There are no tests of the new `MConnTransport`, as this code is likely to evolve as we proceed with the P2P refactor, but tests should be added before a final release. The E2E tests are sufficient for basic validation in the meanwhile.
4 years ago
p2p: implement new Transport interface (#5791) This implements a new `Transport` interface and related types for the P2P refactor in #5670. Previously, `conn.MConnection` was very tightly coupled to the `Peer` implementation -- in order to allow alternative non-multiplexed transports (e.g. QUIC), MConnection has now been moved below the `Transport` interface, as `MConnTransport`, and decoupled from the peer. Since the `p2p` package is not covered by our Go API stability, this is not considered a breaking change, and not listed in the changelog. The initial approach was to implement the new interface in its final form (which also involved possible protocol changes, see https://github.com/tendermint/spec/pull/227). However, it turned out that this would require a large amount of changes to existing P2P code because of the previous tight coupling between `Peer` and `MConnection` and the reliance on subtleties in the MConnection behavior. Instead, I have broadened the `Transport` interface to expose much of the existing MConnection interface, preserved much of the existing MConnection logic and behavior in the transport implementation, and tried to make as few changes to the rest of the P2P stack as possible. We will instead reduce this interface gradually as we refactor other parts of the P2P stack. The low-level transport code and protocol (e.g. MConnection, SecretConnection and so on) has not been significantly changed, and refactoring this is not a priority until we come up with a plan for QUIC adoption, as we may end up discarding the MConnection code entirely. There are no tests of the new `MConnTransport`, as this code is likely to evolve as we proceed with the P2P refactor, but tests should be added before a final release. The E2E tests are sufficient for basic validation in the meanwhile.
4 years ago
p2p: implement new Transport interface (#5791) This implements a new `Transport` interface and related types for the P2P refactor in #5670. Previously, `conn.MConnection` was very tightly coupled to the `Peer` implementation -- in order to allow alternative non-multiplexed transports (e.g. QUIC), MConnection has now been moved below the `Transport` interface, as `MConnTransport`, and decoupled from the peer. Since the `p2p` package is not covered by our Go API stability, this is not considered a breaking change, and not listed in the changelog. The initial approach was to implement the new interface in its final form (which also involved possible protocol changes, see https://github.com/tendermint/spec/pull/227). However, it turned out that this would require a large amount of changes to existing P2P code because of the previous tight coupling between `Peer` and `MConnection` and the reliance on subtleties in the MConnection behavior. Instead, I have broadened the `Transport` interface to expose much of the existing MConnection interface, preserved much of the existing MConnection logic and behavior in the transport implementation, and tried to make as few changes to the rest of the P2P stack as possible. We will instead reduce this interface gradually as we refactor other parts of the P2P stack. The low-level transport code and protocol (e.g. MConnection, SecretConnection and so on) has not been significantly changed, and refactoring this is not a priority until we come up with a plan for QUIC adoption, as we may end up discarding the MConnection code entirely. There are no tests of the new `MConnTransport`, as this code is likely to evolve as we proceed with the P2P refactor, but tests should be added before a final release. The E2E tests are sufficient for basic validation in the meanwhile.
4 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
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: implement new Transport interface (#5791) This implements a new `Transport` interface and related types for the P2P refactor in #5670. Previously, `conn.MConnection` was very tightly coupled to the `Peer` implementation -- in order to allow alternative non-multiplexed transports (e.g. QUIC), MConnection has now been moved below the `Transport` interface, as `MConnTransport`, and decoupled from the peer. Since the `p2p` package is not covered by our Go API stability, this is not considered a breaking change, and not listed in the changelog. The initial approach was to implement the new interface in its final form (which also involved possible protocol changes, see https://github.com/tendermint/spec/pull/227). However, it turned out that this would require a large amount of changes to existing P2P code because of the previous tight coupling between `Peer` and `MConnection` and the reliance on subtleties in the MConnection behavior. Instead, I have broadened the `Transport` interface to expose much of the existing MConnection interface, preserved much of the existing MConnection logic and behavior in the transport implementation, and tried to make as few changes to the rest of the P2P stack as possible. We will instead reduce this interface gradually as we refactor other parts of the P2P stack. The low-level transport code and protocol (e.g. MConnection, SecretConnection and so on) has not been significantly changed, and refactoring this is not a priority until we come up with a plan for QUIC adoption, as we may end up discarding the MConnection code entirely. There are no tests of the new `MConnTransport`, as this code is likely to evolve as we proceed with the P2P refactor, but tests should be added before a final release. The E2E tests are sufficient for basic validation in the meanwhile.
4 years ago
p2p: implement new Transport interface (#5791) This implements a new `Transport` interface and related types for the P2P refactor in #5670. Previously, `conn.MConnection` was very tightly coupled to the `Peer` implementation -- in order to allow alternative non-multiplexed transports (e.g. QUIC), MConnection has now been moved below the `Transport` interface, as `MConnTransport`, and decoupled from the peer. Since the `p2p` package is not covered by our Go API stability, this is not considered a breaking change, and not listed in the changelog. The initial approach was to implement the new interface in its final form (which also involved possible protocol changes, see https://github.com/tendermint/spec/pull/227). However, it turned out that this would require a large amount of changes to existing P2P code because of the previous tight coupling between `Peer` and `MConnection` and the reliance on subtleties in the MConnection behavior. Instead, I have broadened the `Transport` interface to expose much of the existing MConnection interface, preserved much of the existing MConnection logic and behavior in the transport implementation, and tried to make as few changes to the rest of the P2P stack as possible. We will instead reduce this interface gradually as we refactor other parts of the P2P stack. The low-level transport code and protocol (e.g. MConnection, SecretConnection and so on) has not been significantly changed, and refactoring this is not a priority until we come up with a plan for QUIC adoption, as we may end up discarding the MConnection code entirely. There are no tests of the new `MConnTransport`, as this code is likely to evolve as we proceed with the P2P refactor, but tests should be added before a final release. The E2E tests are sufficient for basic validation in the meanwhile.
4 years ago
  1. package p2p
  2. import (
  3. "bytes"
  4. "context"
  5. "errors"
  6. "fmt"
  7. "io/ioutil"
  8. "net"
  9. "net/http"
  10. "net/http/httptest"
  11. "regexp"
  12. "strconv"
  13. "sync/atomic"
  14. "testing"
  15. "time"
  16. "github.com/prometheus/client_golang/prometheus/promhttp"
  17. "github.com/stretchr/testify/assert"
  18. "github.com/stretchr/testify/require"
  19. "github.com/tendermint/tendermint/config"
  20. "github.com/tendermint/tendermint/crypto/ed25519"
  21. "github.com/tendermint/tendermint/libs/log"
  22. tmsync "github.com/tendermint/tendermint/libs/sync"
  23. "github.com/tendermint/tendermint/p2p/conn"
  24. )
  25. var (
  26. cfg *config.P2PConfig
  27. ctx = context.Background()
  28. )
  29. func init() {
  30. cfg = config.DefaultP2PConfig()
  31. cfg.PexReactor = true
  32. cfg.AllowDuplicateIP = true
  33. }
  34. type PeerMessage struct {
  35. PeerID NodeID
  36. Bytes []byte
  37. Counter int
  38. }
  39. type TestReactor struct {
  40. BaseReactor
  41. mtx tmsync.Mutex
  42. channels []*conn.ChannelDescriptor
  43. logMessages bool
  44. msgsCounter int
  45. msgsReceived map[byte][]PeerMessage
  46. }
  47. func NewTestReactor(channels []*conn.ChannelDescriptor, logMessages bool) *TestReactor {
  48. tr := &TestReactor{
  49. channels: channels,
  50. logMessages: logMessages,
  51. msgsReceived: make(map[byte][]PeerMessage),
  52. }
  53. tr.BaseReactor = *NewBaseReactor("TestReactor", tr)
  54. tr.SetLogger(log.TestingLogger())
  55. return tr
  56. }
  57. func (tr *TestReactor) GetChannels() []*conn.ChannelDescriptor {
  58. return tr.channels
  59. }
  60. func (tr *TestReactor) AddPeer(peer Peer) {}
  61. func (tr *TestReactor) RemovePeer(peer Peer, reason interface{}) {}
  62. func (tr *TestReactor) Receive(chID byte, peer Peer, msgBytes []byte) {
  63. if tr.logMessages {
  64. tr.mtx.Lock()
  65. defer tr.mtx.Unlock()
  66. // fmt.Printf("Received: %X, %X\n", chID, msgBytes)
  67. tr.msgsReceived[chID] = append(tr.msgsReceived[chID], PeerMessage{peer.ID(), msgBytes, tr.msgsCounter})
  68. tr.msgsCounter++
  69. }
  70. }
  71. func (tr *TestReactor) getMsgs(chID byte) []PeerMessage {
  72. tr.mtx.Lock()
  73. defer tr.mtx.Unlock()
  74. return tr.msgsReceived[chID]
  75. }
  76. //-----------------------------------------------------------------------------
  77. // convenience method for creating two switches connected to each other.
  78. // XXX: note this uses net.Pipe and not a proper TCP conn
  79. func MakeSwitchPair(t testing.TB, initSwitch func(int, *Switch) *Switch) (*Switch, *Switch) {
  80. // Create two switches that will be interconnected.
  81. switches := MakeConnectedSwitches(cfg, 2, initSwitch, Connect2Switches)
  82. return switches[0], switches[1]
  83. }
  84. func initSwitchFunc(i int, sw *Switch) *Switch {
  85. sw.SetAddrBook(&AddrBookMock{
  86. Addrs: make(map[string]struct{}),
  87. OurAddrs: make(map[string]struct{})})
  88. // Make two reactors of two channels each
  89. sw.AddReactor("foo", NewTestReactor([]*conn.ChannelDescriptor{
  90. {ID: byte(0x00), Priority: 10},
  91. {ID: byte(0x01), Priority: 10},
  92. }, true))
  93. sw.AddReactor("bar", NewTestReactor([]*conn.ChannelDescriptor{
  94. {ID: byte(0x02), Priority: 10},
  95. {ID: byte(0x03), Priority: 10},
  96. }, true))
  97. return sw
  98. }
  99. func TestSwitches(t *testing.T) {
  100. s1, s2 := MakeSwitchPair(t, initSwitchFunc)
  101. t.Cleanup(func() {
  102. if err := s1.Stop(); err != nil {
  103. t.Error(err)
  104. }
  105. })
  106. t.Cleanup(func() {
  107. if err := s2.Stop(); err != nil {
  108. t.Error(err)
  109. }
  110. })
  111. if s1.Peers().Size() != 1 {
  112. t.Errorf("expected exactly 1 peer in s1, got %v", s1.Peers().Size())
  113. }
  114. if s2.Peers().Size() != 1 {
  115. t.Errorf("expected exactly 1 peer in s2, got %v", s2.Peers().Size())
  116. }
  117. // Lets send some messages
  118. ch0Msg := []byte("channel zero")
  119. ch1Msg := []byte("channel foo")
  120. ch2Msg := []byte("channel bar")
  121. s1.Broadcast(byte(0x00), ch0Msg)
  122. s1.Broadcast(byte(0x01), ch1Msg)
  123. s1.Broadcast(byte(0x02), ch2Msg)
  124. assertMsgReceivedWithTimeout(t,
  125. ch0Msg,
  126. byte(0x00),
  127. s2.Reactor("foo").(*TestReactor), 10*time.Millisecond, 5*time.Second)
  128. assertMsgReceivedWithTimeout(t,
  129. ch1Msg,
  130. byte(0x01),
  131. s2.Reactor("foo").(*TestReactor), 10*time.Millisecond, 5*time.Second)
  132. assertMsgReceivedWithTimeout(t,
  133. ch2Msg,
  134. byte(0x02),
  135. s2.Reactor("bar").(*TestReactor), 10*time.Millisecond, 5*time.Second)
  136. }
  137. func assertMsgReceivedWithTimeout(
  138. t *testing.T,
  139. msgBytes []byte,
  140. channel byte,
  141. reactor *TestReactor,
  142. checkPeriod,
  143. timeout time.Duration,
  144. ) {
  145. ticker := time.NewTicker(checkPeriod)
  146. for {
  147. select {
  148. case <-ticker.C:
  149. msgs := reactor.getMsgs(channel)
  150. if len(msgs) > 0 {
  151. if !bytes.Equal(msgs[0].Bytes, msgBytes) {
  152. t.Fatalf("Unexpected message bytes. Wanted: %X, Got: %X", msgBytes, msgs[0].Bytes)
  153. }
  154. return
  155. }
  156. case <-time.After(timeout):
  157. t.Fatalf("Expected to have received 1 message in channel #%v, got zero", channel)
  158. }
  159. }
  160. }
  161. func TestSwitchFiltersOutItself(t *testing.T) {
  162. s1 := MakeSwitch(cfg, 1, "127.0.0.1", "123.123.123", initSwitchFunc)
  163. // simulate s1 having a public IP by creating a remote peer with the same ID
  164. rp := &remotePeer{PrivKey: s1.nodeKey.PrivKey, Config: cfg}
  165. rp.Start()
  166. // addr should be rejected in addPeer based on the same ID
  167. err := s1.DialPeerWithAddress(rp.Addr())
  168. if assert.Error(t, err) {
  169. if err, ok := err.(ErrRejected); ok {
  170. if !err.IsSelf() {
  171. t.Errorf("expected self to be rejected")
  172. }
  173. } else {
  174. t.Errorf("expected ErrRejected")
  175. }
  176. }
  177. assert.True(t, s1.addrBook.OurAddress(rp.Addr()))
  178. assert.False(t, s1.addrBook.HasAddress(rp.Addr()))
  179. rp.Stop()
  180. assertNoPeersAfterTimeout(t, s1, 100*time.Millisecond)
  181. }
  182. func TestSwitchPeerFilter(t *testing.T) {
  183. var (
  184. filters = []PeerFilterFunc{
  185. func(_ IPeerSet, _ Peer) error { return nil },
  186. func(_ IPeerSet, _ Peer) error { return fmt.Errorf("denied") },
  187. func(_ IPeerSet, _ Peer) error { return nil },
  188. }
  189. sw = MakeSwitch(
  190. cfg,
  191. 1,
  192. "testing",
  193. "123.123.123",
  194. initSwitchFunc,
  195. SwitchPeerFilters(filters...),
  196. )
  197. )
  198. err := sw.Start()
  199. require.NoError(t, err)
  200. t.Cleanup(func() {
  201. if err := sw.Stop(); err != nil {
  202. t.Error(err)
  203. }
  204. })
  205. // simulate remote peer
  206. rp := &remotePeer{PrivKey: ed25519.GenPrivKey(), Config: cfg}
  207. rp.Start()
  208. t.Cleanup(rp.Stop)
  209. c, err := sw.transport.Dial(ctx, rp.Addr().Endpoint())
  210. if err != nil {
  211. t.Fatal(err)
  212. }
  213. peerInfo, _, err := c.Handshake(ctx, sw.nodeInfo, sw.nodeKey.PrivKey)
  214. if err != nil {
  215. t.Fatal(err)
  216. }
  217. p := newPeer(
  218. peerInfo,
  219. newPeerConn(true, false, c),
  220. sw.reactorsByCh,
  221. sw.StopPeerForError,
  222. )
  223. err = sw.addPeer(p)
  224. if err, ok := err.(ErrRejected); ok {
  225. if !err.IsFiltered() {
  226. t.Errorf("expected peer to be filtered")
  227. }
  228. } else {
  229. t.Errorf("expected ErrRejected")
  230. }
  231. }
  232. func TestSwitchPeerFilterTimeout(t *testing.T) {
  233. var (
  234. filters = []PeerFilterFunc{
  235. func(_ IPeerSet, _ Peer) error {
  236. time.Sleep(10 * time.Millisecond)
  237. return nil
  238. },
  239. }
  240. sw = MakeSwitch(
  241. cfg,
  242. 1,
  243. "testing",
  244. "123.123.123",
  245. initSwitchFunc,
  246. SwitchFilterTimeout(5*time.Millisecond),
  247. SwitchPeerFilters(filters...),
  248. )
  249. )
  250. err := sw.Start()
  251. require.NoError(t, err)
  252. t.Cleanup(func() {
  253. if err := sw.Stop(); err != nil {
  254. t.Log(err)
  255. }
  256. })
  257. // simulate remote peer
  258. rp := &remotePeer{PrivKey: ed25519.GenPrivKey(), Config: cfg}
  259. rp.Start()
  260. defer rp.Stop()
  261. c, err := sw.transport.Dial(ctx, rp.Addr().Endpoint())
  262. if err != nil {
  263. t.Fatal(err)
  264. }
  265. peerInfo, _, err := c.Handshake(ctx, sw.nodeInfo, sw.nodeKey.PrivKey)
  266. if err != nil {
  267. t.Fatal(err)
  268. }
  269. p := newPeer(
  270. peerInfo,
  271. newPeerConn(true, false, c),
  272. sw.reactorsByCh,
  273. sw.StopPeerForError,
  274. )
  275. err = sw.addPeer(p)
  276. if _, ok := err.(ErrFilterTimeout); !ok {
  277. t.Errorf("expected ErrFilterTimeout")
  278. }
  279. }
  280. func TestSwitchPeerFilterDuplicate(t *testing.T) {
  281. sw := MakeSwitch(cfg, 1, "testing", "123.123.123", initSwitchFunc)
  282. err := sw.Start()
  283. require.NoError(t, err)
  284. t.Cleanup(func() {
  285. if err := sw.Stop(); err != nil {
  286. t.Error(err)
  287. }
  288. })
  289. // simulate remote peer
  290. rp := &remotePeer{PrivKey: ed25519.GenPrivKey(), Config: cfg}
  291. rp.Start()
  292. defer rp.Stop()
  293. c, err := sw.transport.Dial(ctx, rp.Addr().Endpoint())
  294. if err != nil {
  295. t.Fatal(err)
  296. }
  297. peerInfo, _, err := c.Handshake(ctx, sw.nodeInfo, sw.nodeKey.PrivKey)
  298. if err != nil {
  299. t.Fatal(err)
  300. }
  301. p := newPeer(
  302. peerInfo,
  303. newPeerConn(true, false, c),
  304. sw.reactorsByCh,
  305. sw.StopPeerForError,
  306. )
  307. if err := sw.addPeer(p); err != nil {
  308. t.Fatal(err)
  309. }
  310. err = sw.addPeer(p)
  311. if errRej, ok := err.(ErrRejected); ok {
  312. if !errRej.IsDuplicate() {
  313. t.Errorf("expected peer to be duplicate. got %v", errRej)
  314. }
  315. } else {
  316. t.Errorf("expected ErrRejected, got %v", err)
  317. }
  318. }
  319. func assertNoPeersAfterTimeout(t *testing.T, sw *Switch, timeout time.Duration) {
  320. time.Sleep(timeout)
  321. if sw.Peers().Size() != 0 {
  322. t.Fatalf("Expected %v to not connect to some peers, got %d", sw, sw.Peers().Size())
  323. }
  324. }
  325. func TestSwitchStopsNonPersistentPeerOnError(t *testing.T) {
  326. assert, require := assert.New(t), require.New(t)
  327. sw := MakeSwitch(cfg, 1, "testing", "123.123.123", initSwitchFunc)
  328. err := sw.Start()
  329. if err != nil {
  330. t.Error(err)
  331. }
  332. t.Cleanup(func() {
  333. if err := sw.Stop(); err != nil {
  334. t.Error(err)
  335. }
  336. })
  337. // simulate remote peer
  338. rp := &remotePeer{PrivKey: ed25519.GenPrivKey(), Config: cfg}
  339. rp.Start()
  340. defer rp.Stop()
  341. c, err := sw.transport.Dial(ctx, rp.Addr().Endpoint())
  342. if err != nil {
  343. t.Fatal(err)
  344. }
  345. peerInfo, _, err := c.Handshake(ctx, sw.nodeInfo, sw.nodeKey.PrivKey)
  346. if err != nil {
  347. t.Fatal(err)
  348. }
  349. p := newPeer(
  350. peerInfo,
  351. newPeerConn(true, false, c),
  352. sw.reactorsByCh,
  353. sw.StopPeerForError,
  354. )
  355. err = sw.addPeer(p)
  356. require.Nil(err)
  357. require.NotNil(sw.Peers().Get(rp.ID()))
  358. // simulate failure by closing connection
  359. err = p.CloseConn()
  360. require.NoError(err)
  361. assertNoPeersAfterTimeout(t, sw, 100*time.Millisecond)
  362. assert.False(p.IsRunning())
  363. }
  364. func TestSwitchStopPeerForError(t *testing.T) {
  365. s := httptest.NewServer(promhttp.Handler())
  366. defer s.Close()
  367. scrapeMetrics := func() string {
  368. resp, err := http.Get(s.URL)
  369. require.NoError(t, err)
  370. defer resp.Body.Close()
  371. buf, _ := ioutil.ReadAll(resp.Body)
  372. return string(buf)
  373. }
  374. namespace, subsystem, name := config.TestInstrumentationConfig().Namespace, MetricsSubsystem, "peers"
  375. re := regexp.MustCompile(namespace + `_` + subsystem + `_` + name + ` ([0-9\.]+)`)
  376. peersMetricValue := func() float64 {
  377. matches := re.FindStringSubmatch(scrapeMetrics())
  378. f, _ := strconv.ParseFloat(matches[1], 64)
  379. return f
  380. }
  381. p2pMetrics := PrometheusMetrics(namespace)
  382. // make two connected switches
  383. sw1, sw2 := MakeSwitchPair(t, func(i int, sw *Switch) *Switch {
  384. // set metrics on sw1
  385. if i == 0 {
  386. opt := WithMetrics(p2pMetrics)
  387. opt(sw)
  388. }
  389. return initSwitchFunc(i, sw)
  390. })
  391. assert.Equal(t, len(sw1.Peers().List()), 1)
  392. assert.EqualValues(t, 1, peersMetricValue())
  393. // send messages to the peer from sw1
  394. p := sw1.Peers().List()[0]
  395. p.Send(0x1, []byte("here's a message to send"))
  396. // stop sw2. this should cause the p to fail,
  397. // which results in calling StopPeerForError internally
  398. t.Cleanup(func() {
  399. if err := sw2.Stop(); err != nil {
  400. t.Error(err)
  401. }
  402. })
  403. // now call StopPeerForError explicitly, eg. from a reactor
  404. sw1.StopPeerForError(p, fmt.Errorf("some err"))
  405. assert.Equal(t, len(sw1.Peers().List()), 0)
  406. assert.EqualValues(t, 0, peersMetricValue())
  407. }
  408. func TestSwitchReconnectsToOutboundPersistentPeer(t *testing.T) {
  409. sw := MakeSwitch(cfg, 1, "testing", "123.123.123", initSwitchFunc)
  410. err := sw.Start()
  411. require.NoError(t, err)
  412. t.Cleanup(func() {
  413. if err := sw.Stop(); err != nil {
  414. t.Error(err)
  415. }
  416. })
  417. // 1. simulate failure by closing connection
  418. rp := &remotePeer{PrivKey: ed25519.GenPrivKey(), Config: cfg}
  419. rp.Start()
  420. defer rp.Stop()
  421. err = sw.AddPersistentPeers([]string{rp.Addr().String()})
  422. require.NoError(t, err)
  423. err = sw.DialPeerWithAddress(rp.Addr())
  424. require.Nil(t, err)
  425. require.NotNil(t, sw.Peers().Get(rp.ID()))
  426. p := sw.Peers().List()[0]
  427. err = p.(*peer).CloseConn()
  428. require.NoError(t, err)
  429. waitUntilSwitchHasAtLeastNPeers(sw, 1)
  430. assert.False(t, p.IsRunning()) // old peer instance
  431. assert.Equal(t, 1, sw.Peers().Size()) // new peer instance
  432. // 2. simulate first time dial failure
  433. rp = &remotePeer{
  434. PrivKey: ed25519.GenPrivKey(),
  435. Config: cfg,
  436. // Use different interface to prevent duplicate IP filter, this will break
  437. // beyond two peers.
  438. listenAddr: "127.0.0.1:0",
  439. }
  440. rp.Start()
  441. defer rp.Stop()
  442. conf := config.DefaultP2PConfig()
  443. conf.TestDialFail = true // will trigger a reconnect
  444. err = sw.addOutboundPeerWithConfig(rp.Addr(), conf)
  445. require.NotNil(t, err)
  446. // DialPeerWithAddres - sw.peerConfig resets the dialer
  447. waitUntilSwitchHasAtLeastNPeers(sw, 2)
  448. assert.Equal(t, 2, sw.Peers().Size())
  449. }
  450. func TestSwitchReconnectsToInboundPersistentPeer(t *testing.T) {
  451. sw := MakeSwitch(cfg, 1, "testing", "123.123.123", initSwitchFunc)
  452. err := sw.Start()
  453. require.NoError(t, err)
  454. t.Cleanup(func() {
  455. if err := sw.Stop(); err != nil {
  456. t.Error(err)
  457. }
  458. })
  459. // 1. simulate failure by closing the connection
  460. rp := &remotePeer{PrivKey: ed25519.GenPrivKey(), Config: cfg}
  461. rp.Start()
  462. defer rp.Stop()
  463. err = sw.AddPersistentPeers([]string{rp.Addr().String()})
  464. require.NoError(t, err)
  465. conn, err := rp.Dial(sw.NetAddress())
  466. require.NoError(t, err)
  467. time.Sleep(50 * time.Millisecond)
  468. require.NotNil(t, sw.Peers().Get(rp.ID()))
  469. conn.Close()
  470. waitUntilSwitchHasAtLeastNPeers(sw, 1)
  471. assert.Equal(t, 1, sw.Peers().Size())
  472. }
  473. func TestSwitchDialPeersAsync(t *testing.T) {
  474. if testing.Short() {
  475. return
  476. }
  477. sw := MakeSwitch(cfg, 1, "testing", "123.123.123", initSwitchFunc)
  478. err := sw.Start()
  479. require.NoError(t, err)
  480. t.Cleanup(func() {
  481. if err := sw.Stop(); err != nil {
  482. t.Error(err)
  483. }
  484. })
  485. rp := &remotePeer{PrivKey: ed25519.GenPrivKey(), Config: cfg}
  486. rp.Start()
  487. defer rp.Stop()
  488. err = sw.DialPeersAsync([]string{rp.Addr().String()})
  489. require.NoError(t, err)
  490. time.Sleep(dialRandomizerIntervalMilliseconds * time.Millisecond)
  491. require.NotNil(t, sw.Peers().Get(rp.ID()))
  492. }
  493. func waitUntilSwitchHasAtLeastNPeers(sw *Switch, n int) {
  494. for i := 0; i < 20; i++ {
  495. time.Sleep(250 * time.Millisecond)
  496. has := sw.Peers().Size()
  497. if has >= n {
  498. break
  499. }
  500. }
  501. }
  502. func TestSwitchFullConnectivity(t *testing.T) {
  503. switches := MakeConnectedSwitches(cfg, 3, initSwitchFunc, Connect2Switches)
  504. defer func() {
  505. for _, sw := range switches {
  506. sw := sw
  507. t.Cleanup(func() {
  508. if err := sw.Stop(); err != nil {
  509. t.Error(err)
  510. }
  511. })
  512. }
  513. }()
  514. for i, sw := range switches {
  515. if sw.Peers().Size() != 2 {
  516. t.Fatalf("Expected each switch to be connected to 2 other, but %d switch only connected to %d", sw.Peers().Size(), i)
  517. }
  518. }
  519. }
  520. func TestSwitchAcceptRoutine(t *testing.T) {
  521. cfg.MaxNumInboundPeers = 5
  522. // Create some unconditional peers.
  523. const unconditionalPeersNum = 2
  524. var (
  525. unconditionalPeers = make([]*remotePeer, unconditionalPeersNum)
  526. unconditionalPeerIDs = make([]string, unconditionalPeersNum)
  527. )
  528. for i := 0; i < unconditionalPeersNum; i++ {
  529. peer := &remotePeer{PrivKey: ed25519.GenPrivKey(), Config: cfg}
  530. peer.Start()
  531. unconditionalPeers[i] = peer
  532. unconditionalPeerIDs[i] = string(peer.ID())
  533. }
  534. // make switch
  535. sw := MakeSwitch(cfg, 1, "testing", "123.123.123", initSwitchFunc)
  536. err := sw.AddUnconditionalPeerIDs(unconditionalPeerIDs)
  537. require.NoError(t, err)
  538. err = sw.Start()
  539. require.NoError(t, err)
  540. t.Cleanup(func() {
  541. err := sw.Stop()
  542. require.NoError(t, err)
  543. })
  544. // 0. check there are no peers
  545. assert.Equal(t, 0, sw.Peers().Size())
  546. // 1. check we connect up to MaxNumInboundPeers
  547. peers := make([]*remotePeer, 0)
  548. for i := 0; i < cfg.MaxNumInboundPeers; i++ {
  549. peer := &remotePeer{PrivKey: ed25519.GenPrivKey(), Config: cfg}
  550. peers = append(peers, peer)
  551. peer.Start()
  552. c, err := peer.Dial(sw.NetAddress())
  553. require.NoError(t, err)
  554. // spawn a reading routine to prevent connection from closing
  555. go func(c net.Conn) {
  556. for {
  557. one := make([]byte, 1)
  558. _, err := c.Read(one)
  559. if err != nil {
  560. return
  561. }
  562. }
  563. }(c)
  564. }
  565. time.Sleep(100 * time.Millisecond)
  566. assert.Equal(t, cfg.MaxNumInboundPeers, sw.Peers().Size())
  567. // 2. check we close new connections if we already have MaxNumInboundPeers peers
  568. peer := &remotePeer{PrivKey: ed25519.GenPrivKey(), Config: cfg}
  569. peer.Start()
  570. conn, err := peer.Dial(sw.NetAddress())
  571. require.NoError(t, err)
  572. // check conn is closed
  573. one := make([]byte, 1)
  574. _ = conn.SetReadDeadline(time.Now().Add(10 * time.Millisecond))
  575. _, err = conn.Read(one)
  576. assert.Error(t, err)
  577. assert.Equal(t, cfg.MaxNumInboundPeers, sw.Peers().Size())
  578. peer.Stop()
  579. // 3. check we connect to unconditional peers despite the limit.
  580. for _, peer := range unconditionalPeers {
  581. c, err := peer.Dial(sw.NetAddress())
  582. require.NoError(t, err)
  583. // spawn a reading routine to prevent connection from closing
  584. go func(c net.Conn) {
  585. for {
  586. one := make([]byte, 1)
  587. _, err := c.Read(one)
  588. if err != nil {
  589. return
  590. }
  591. }
  592. }(c)
  593. }
  594. time.Sleep(10 * time.Millisecond)
  595. assert.Equal(t, cfg.MaxNumInboundPeers+unconditionalPeersNum, sw.Peers().Size())
  596. for _, peer := range peers {
  597. peer.Stop()
  598. }
  599. for _, peer := range unconditionalPeers {
  600. peer.Stop()
  601. }
  602. }
  603. type errorTransport struct {
  604. acceptErr error
  605. }
  606. func (et errorTransport) String() string {
  607. return "error"
  608. }
  609. func (et errorTransport) Protocols() []Protocol {
  610. return []Protocol{"error"}
  611. }
  612. func (et errorTransport) Accept() (Connection, error) {
  613. return nil, et.acceptErr
  614. }
  615. func (errorTransport) Dial(context.Context, Endpoint) (Connection, error) {
  616. panic("not implemented")
  617. }
  618. func (errorTransport) Close() error { panic("not implemented") }
  619. func (errorTransport) FlushClose() error { panic("not implemented") }
  620. func (errorTransport) Endpoints() []Endpoint { panic("not implemented") }
  621. func TestSwitchAcceptRoutineErrorCases(t *testing.T) {
  622. sw := NewSwitch(cfg, errorTransport{ErrFilterTimeout{}})
  623. assert.NotPanics(t, func() {
  624. err := sw.Start()
  625. require.NoError(t, err)
  626. err = sw.Stop()
  627. require.NoError(t, err)
  628. })
  629. sw = NewSwitch(cfg, errorTransport{ErrRejected{conn: nil, err: errors.New("filtered"), isFiltered: true}})
  630. assert.NotPanics(t, func() {
  631. err := sw.Start()
  632. require.NoError(t, err)
  633. err = sw.Stop()
  634. require.NoError(t, err)
  635. })
  636. // TODO(melekes) check we remove our address from addrBook
  637. sw = NewSwitch(cfg, errorTransport{ErrTransportClosed{}})
  638. assert.NotPanics(t, func() {
  639. err := sw.Start()
  640. require.NoError(t, err)
  641. err = sw.Stop()
  642. require.NoError(t, err)
  643. })
  644. }
  645. // mockReactor checks that InitPeer never called before RemovePeer. If that's
  646. // not true, InitCalledBeforeRemoveFinished will return true.
  647. type mockReactor struct {
  648. *BaseReactor
  649. // atomic
  650. removePeerInProgress uint32
  651. initCalledBeforeRemoveFinished uint32
  652. }
  653. func (r *mockReactor) GetChannels() []*ChannelDescriptor {
  654. return []*ChannelDescriptor{{ID: testCh, Priority: 10}}
  655. }
  656. func (r *mockReactor) RemovePeer(peer Peer, reason interface{}) {
  657. atomic.StoreUint32(&r.removePeerInProgress, 1)
  658. defer atomic.StoreUint32(&r.removePeerInProgress, 0)
  659. time.Sleep(100 * time.Millisecond)
  660. }
  661. func (r *mockReactor) InitPeer(peer Peer) Peer {
  662. if atomic.LoadUint32(&r.removePeerInProgress) == 1 {
  663. atomic.StoreUint32(&r.initCalledBeforeRemoveFinished, 1)
  664. }
  665. return peer
  666. }
  667. func (r *mockReactor) InitCalledBeforeRemoveFinished() bool {
  668. return atomic.LoadUint32(&r.initCalledBeforeRemoveFinished) == 1
  669. }
  670. // see stopAndRemovePeer
  671. func TestSwitchInitPeerIsNotCalledBeforeRemovePeer(t *testing.T) {
  672. // make reactor
  673. reactor := &mockReactor{}
  674. reactor.BaseReactor = NewBaseReactor("mockReactor", reactor)
  675. // make switch
  676. sw := MakeSwitch(cfg, 1, "testing", "123.123.123", func(i int, sw *Switch) *Switch {
  677. sw.AddReactor("mock", reactor)
  678. return sw
  679. })
  680. err := sw.Start()
  681. require.NoError(t, err)
  682. t.Cleanup(func() {
  683. if err := sw.Stop(); err != nil {
  684. t.Error(err)
  685. }
  686. })
  687. // add peer
  688. rp := &remotePeer{PrivKey: ed25519.GenPrivKey(), Config: cfg}
  689. rp.Start()
  690. defer rp.Stop()
  691. _, err = rp.Dial(sw.NetAddress())
  692. require.NoError(t, err)
  693. // wait till the switch adds rp to the peer set, then stop the peer asynchronously
  694. for {
  695. time.Sleep(20 * time.Millisecond)
  696. if peer := sw.Peers().Get(rp.ID()); peer != nil {
  697. go sw.StopPeerForError(peer, "test")
  698. break
  699. }
  700. }
  701. // simulate peer reconnecting to us
  702. _, err = rp.Dial(sw.NetAddress())
  703. require.NoError(t, err)
  704. // wait till the switch adds rp to the peer set
  705. time.Sleep(50 * time.Millisecond)
  706. // make sure reactor.RemovePeer is finished before InitPeer is called
  707. assert.False(t, reactor.InitCalledBeforeRemoveFinished())
  708. }
  709. func BenchmarkSwitchBroadcast(b *testing.B) {
  710. s1, s2 := MakeSwitchPair(b, func(i int, sw *Switch) *Switch {
  711. // Make bar reactors of bar channels each
  712. sw.AddReactor("foo", NewTestReactor([]*conn.ChannelDescriptor{
  713. {ID: byte(0x00), Priority: 10},
  714. {ID: byte(0x01), Priority: 10},
  715. }, false))
  716. sw.AddReactor("bar", NewTestReactor([]*conn.ChannelDescriptor{
  717. {ID: byte(0x02), Priority: 10},
  718. {ID: byte(0x03), Priority: 10},
  719. }, false))
  720. return sw
  721. })
  722. b.Cleanup(func() {
  723. if err := s1.Stop(); err != nil {
  724. b.Error(err)
  725. }
  726. })
  727. b.Cleanup(func() {
  728. if err := s2.Stop(); err != nil {
  729. b.Error(err)
  730. }
  731. })
  732. // Allow time for goroutines to boot up
  733. time.Sleep(1 * time.Second)
  734. b.ResetTimer()
  735. numSuccess, numFailure := 0, 0
  736. // Send random message from foo channel to another
  737. for i := 0; i < b.N; i++ {
  738. chID := byte(i % 4)
  739. successChan := s1.Broadcast(chID, []byte("test data"))
  740. for s := range successChan {
  741. if s {
  742. numSuccess++
  743. } else {
  744. numFailure++
  745. }
  746. }
  747. }
  748. b.Logf("success: %v, failure: %v", numSuccess, numFailure)
  749. }