From 12f7b62349ca466b324435cc39fbc5ea31e10567 Mon Sep 17 00:00:00 2001 From: Jonathan Zernik Date: Sat, 9 Oct 2021 22:26:54 -0700 Subject: [PATCH] Add toggle for connect with tor (#1550) * Added use_tor option to peer address class and grpc message * Got itest passing without tor * Got peer connection working in UI with tor toggle * Able to connect to with and without tor * Got save peer working with tor and without tor * Add use_tor field to peer address everywhere. * Fix usage of useMemo in peer address page --- docker/docker-compose.yml | 2 - docker/test/Dockerfile | 1 + .../ConnectPeerDialog/ConnectPeerDialog.js | 29 ++++++- .../CreatePeerDialog/CreatePeerDialog.js | 31 +++++++- frontend/src/components/Layout/Layout.js | 2 +- .../components/PeerListItem/PeerListItem.js | 3 +- frontend/src/navigation/navigation.js | 5 +- frontend/src/pages/peer/Peer.js | 10 +++ frontend/src/pages/peeraddress/PeerAddress.js | 22 +++--- frontend/src/pages/peers/Peers.js | 2 +- frontend/src/squeakclient/requests.js | 15 ++-- itests/tests/util.py | 1 + proto/squeak_admin.proto | 3 + squeaknode/admin/messages.py | 2 + .../admin/squeak_admin_server_handler.py | 1 + squeaknode/core/peer_address.py | 1 + squeaknode/core/peers.py | 6 +- squeaknode/core/squeak_core.py | 1 + ..._add_use_tor_column_to_all_tables_with_.py | 77 +++++++++++++++++++ squeaknode/db/models.py | 5 ++ squeaknode/db/squeak_db.py | 12 +++ squeaknode/network/network_manager.py | 14 ++-- squeaknode/network/peer_client.py | 15 +++- squeaknode/network/peer_server.py | 1 + tests/core/test_peers.py | 37 ++++++++- tests/network/test_connection_manager.py | 5 +- tests/node/test_squeak_controller.py | 5 +- 27 files changed, 259 insertions(+), 49 deletions(-) create mode 100644 squeaknode/db/alembic/versions/231b8b35ed2e_add_use_tor_column_to_all_tables_with_.py diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 80c05516..8eb98c17 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -58,8 +58,6 @@ services: tor-socks-proxy: container_name: tor-socks-proxy image: peterdavehello/tor-socks-proxy:latest - ports: - - 9150:9150 restart: unless-stopped squeaknode: diff --git a/docker/test/Dockerfile b/docker/test/Dockerfile index 76fefc46..f5be6fae 100644 --- a/docker/test/Dockerfile +++ b/docker/test/Dockerfile @@ -7,6 +7,7 @@ RUN pip3 install -r requirements-itest.txt WORKDIR /app COPY proto ./proto +COPY itests/test.sh ./ COPY itests/tests ./tests RUN python3 -m grpc_tools.protoc --proto_path=. --python_out=. --grpc_python_out=. \ diff --git a/frontend/src/components/ConnectPeerDialog/ConnectPeerDialog.js b/frontend/src/components/ConnectPeerDialog/ConnectPeerDialog.js index ab13d8ab..038eb163 100644 --- a/frontend/src/components/ConnectPeerDialog/ConnectPeerDialog.js +++ b/frontend/src/components/ConnectPeerDialog/ConnectPeerDialog.js @@ -32,6 +32,7 @@ export default function ConnectPeerDialog({ const [host, setHost] = useState(''); const [port, setPort] = useState(''); const [customPortChecked, setCustomPortChecked] = useState(false); + const [useTorChecked, setUseTorChecked] = useState(false); const [loading, setLoading] = useState(false); const resetFields = () => { @@ -56,9 +57,13 @@ export default function ConnectPeerDialog({ setPort(event.target.value); }; + const handleChangeUseTorChecked = (event) => { + setUseTorChecked(event.target.checked); + }; + const connectPeer = (peerName, host, port) => { setLoading(true); - connectSqueakPeerRequest(host, port, (response) => { + connectSqueakPeerRequest(host, port, useTorChecked, (response) => { // goToPeerPage(history, response.getPeerId()); // handlePeerConnected(); handlePeerConnectedResponse(); @@ -141,6 +146,23 @@ export default function ConnectPeerDialog({ ); } + function UseTorSwitch() { + return ( + + )} + label="Use Tor" + /> + ); + } + function CancelButton() { return ( +
+ Use Tor: {useTor} +
+ ); } diff --git a/frontend/src/pages/peeraddress/PeerAddress.js b/frontend/src/pages/peeraddress/PeerAddress.js index c1aa964a..f5580b43 100644 --- a/frontend/src/pages/peeraddress/PeerAddress.js +++ b/frontend/src/pages/peeraddress/PeerAddress.js @@ -1,4 +1,4 @@ -import React, { useState, useEffect, useCallback } from 'react'; +import React, { useState, useEffect, useCallback, useMemo } from 'react'; import { useParams, useHistory } from 'react-router-dom'; import { Grid, @@ -36,38 +36,40 @@ import { export default function PeerAddressPage() { const classes = useStyles(); const history = useHistory(); - const { host, port } = useParams(); + const { host, port, useTorStr } = useParams(); const [savedPeer, setSavedPeer] = useState(null); const [connectedPeer, setConnectedPeer] = useState(null); const [waitingForConnectedPeer, setWaitingForConnectedPeer] = useState(false); const [createSavedPeerDialogOpen, setCreateSavedPeerDialogOpen] = useState(false); + const useTor = useMemo(() => useTorStr === 'true', [useTorStr]); const getPeer = useCallback(() => { - getPeerByAddressRequest(host, port, setSavedPeer); + getPeerByAddressRequest(host, port, useTor, setSavedPeer); }, - [host, port]); + [host, port, useTor]); const getConnectedPeer = useCallback(() => { setWaitingForConnectedPeer(true); - getConnectedPeerRequest(host, port, handleLoadedConnectedPeer); + getConnectedPeerRequest(host, port, useTor, handleLoadedConnectedPeer); }, - [host, port]); + [host, port, useTor]); const disconnectPeer = useCallback(() => { setWaitingForConnectedPeer(true); - disconnectSqueakPeerRequest(host, port, () => { + disconnectSqueakPeerRequest(host, port, useTor, () => { getConnectedPeer(); }); }, - [host, port, getConnectedPeer]); + [host, port, useTor, getConnectedPeer]); const connectPeer = useCallback(() => { setWaitingForConnectedPeer(true); - connectSqueakPeerRequest(host, port, () => { + console.log("Calling connectSqueakPeerRequest with " + host, port, useTor); + connectSqueakPeerRequest(host, port, useTor, () => { getConnectedPeer(); }, handleConnectPeerError); }, - [host, port, getConnectedPeer]); + [host, port, useTor, getConnectedPeer]); // const subscribeConnectedPeer = useCallback(() => subscribeConnectedPeerRequest(host, port, (connectedPeer) => { // setConnectedPeer(connectedPeer); diff --git a/frontend/src/pages/peers/Peers.js b/frontend/src/pages/peers/Peers.js index e14bc524..46d96ef6 100644 --- a/frontend/src/pages/peers/Peers.js +++ b/frontend/src/pages/peers/Peers.js @@ -106,7 +106,7 @@ export default function Peers() { return connectedPeerAddresses.includes(peerAddressStr); }; - const peerAddressToStr = (peerAddress) => `${peerAddress.getHost()}:${peerAddress.getPort()}`; + const peerAddressToStr = (peerAddress) => `${peerAddress.getUseTor()}/${peerAddress.getHost()}:${peerAddress.getPort()}`; useEffect(() => { getConnectedPeers(); diff --git a/frontend/src/squeakclient/requests.js b/frontend/src/squeakclient/requests.js index 8af9239c..1628abe1 100644 --- a/frontend/src/squeakclient/requests.js +++ b/frontend/src/squeakclient/requests.js @@ -530,11 +530,12 @@ export function getPeerRequest(id, handleResponse) { // }); } -export function getPeerByAddressRequest(host, port, handleResponse) { +export function getPeerByAddressRequest(host, port, useTor, handleResponse) { const request = new GetPeerByAddressRequest(); const peerAddress = new PeerAddress(); peerAddress.setHost(host); peerAddress.setPort(port); + peerAddress.setUseTor(useTor); request.setPeerAddress(peerAddress); makeRequest( 'getpeerbyaddress', @@ -779,11 +780,12 @@ export function importSigningProfileRequest(profileName, privateKey, handleRespo // }); } -export function createPeerRequest(peerName, host, port, handleResponse) { +export function createPeerRequest(peerName, host, port, useTor, handleResponse) { const request = new CreatePeerRequest(); const peerAddress = new PeerAddress(); peerAddress.setHost(host); peerAddress.setPort(port); + peerAddress.setUseTor(useTor); request.setPeerName(peerName); request.setPeerAddress(peerAddress); makeRequest( @@ -1087,11 +1089,12 @@ export function getConnectedPeersRequest(handleResponse) { // }); } -export function getConnectedPeerRequest(host, port, handleResponse) { +export function getConnectedPeerRequest(host, port, useTor, handleResponse) { const request = new GetConnectedPeerRequest(); const peerAddress = new PeerAddress(); peerAddress.setHost(host); peerAddress.setPort(port); + peerAddress.setUseTor(useTor); request.setPeerAddress(peerAddress); makeRequest( 'getconnectedpeer', @@ -1106,11 +1109,12 @@ export function getConnectedPeerRequest(host, port, handleResponse) { // }); } -export function connectSqueakPeerRequest(host, port, handleResponse, handleErr) { +export function connectSqueakPeerRequest(host, port, useTor, handleResponse, handleErr) { const request = new ConnectSqueakPeerRequest(); const peerAddress = new PeerAddress(); peerAddress.setHost(host); peerAddress.setPort(port); + peerAddress.setUseTor(useTor); request.setPeerAddress(peerAddress); makeRequest( 'connectpeer', @@ -1126,11 +1130,12 @@ export function connectSqueakPeerRequest(host, port, handleResponse, handleErr) // }); } -export function disconnectSqueakPeerRequest(host, port, handleResponse) { +export function disconnectSqueakPeerRequest(host, port, useTor, handleResponse) { const request = new DisconnectSqueakPeerRequest(); const peerAddress = new PeerAddress(); peerAddress.setHost(host); peerAddress.setPort(port); + peerAddress.setUseTor(useTor); request.setPeerAddress(peerAddress); makeRequest( 'disconnectpeer', diff --git a/itests/tests/util.py b/itests/tests/util.py index e988d463..6c52d46b 100644 --- a/itests/tests/util.py +++ b/itests/tests/util.py @@ -148,6 +148,7 @@ def open_peer_connection(node_stub, peer_name, peer_host, peer_port): peer_address=squeak_admin_pb2.PeerAddress( host=peer_host, port=peer_port, + use_tor=False, ) ) ) diff --git a/proto/squeak_admin.proto b/proto/squeak_admin.proto index c428438b..58d845e7 100644 --- a/proto/squeak_admin.proto +++ b/proto/squeak_admin.proto @@ -1144,6 +1144,9 @@ message PeerAddress { /// The port of the peer int32 port = 2; + + /// Use tor to connect to this address. + bool use_tor = 3; } message SubscribeBuyOffersRequest { diff --git a/squeaknode/admin/messages.py b/squeaknode/admin/messages.py index 3100f64e..c53a4a85 100644 --- a/squeaknode/admin/messages.py +++ b/squeaknode/admin/messages.py @@ -203,6 +203,7 @@ def peer_address_to_message(peer_address: PeerAddress) -> squeak_admin_pb2.PeerA return squeak_admin_pb2.PeerAddress( host=peer_address.host, port=peer_address.port, + use_tor=peer_address.use_tor, ) @@ -210,6 +211,7 @@ def message_to_peer_address(peer_address: squeak_admin_pb2.PeerAddress) -> PeerA return PeerAddress( host=peer_address.host, port=peer_address.port, + use_tor=peer_address.use_tor, ) diff --git a/squeaknode/admin/squeak_admin_server_handler.py b/squeaknode/admin/squeak_admin_server_handler.py index fc3560ce..d12b0453 100644 --- a/squeaknode/admin/squeak_admin_server_handler.py +++ b/squeaknode/admin/squeak_admin_server_handler.py @@ -526,6 +526,7 @@ class SqueakAdminServerHandler(object): peer_id = request.peer_id logger.info("Handle get squeak peer with id: {}".format(peer_id)) squeak_peer = self.squeak_controller.get_peer(peer_id) + logger.info("Got squeak peer: {}".format(squeak_peer)) if squeak_peer is None: return squeak_admin_pb2.GetPeerReply( squeak_peer=None, diff --git a/squeaknode/core/peer_address.py b/squeaknode/core/peer_address.py index fe70bc85..42ec5bfb 100644 --- a/squeaknode/core/peer_address.py +++ b/squeaknode/core/peer_address.py @@ -26,3 +26,4 @@ class PeerAddress(NamedTuple): """Class for representing a remote peer address.""" host: str port: int + use_tor: bool diff --git a/squeaknode/core/peers.py b/squeaknode/core/peers.py index 7ae07215..0e30a93f 100644 --- a/squeaknode/core/peers.py +++ b/squeaknode/core/peers.py @@ -30,10 +30,8 @@ def create_saved_peer( ) -> SqueakPeer: validate_saved_peer_name(peer_name) port = peer_address.port or default_port - peer_address = PeerAddress( - host=peer_address.host, - port=port, - ) + peer_address = peer_address._replace( + port=port) return SqueakPeer( peer_id=None, peer_name=peer_name, diff --git a/squeaknode/core/squeak_core.py b/squeaknode/core/squeak_core.py index 3d9e478c..cd410cca 100644 --- a/squeaknode/core/squeak_core.py +++ b/squeaknode/core/squeak_core.py @@ -303,6 +303,7 @@ class SqueakCore: peer_address = PeerAddress( host=received_offer.peer_address.host, port=received_offer.peer_address.port, + use_tor=received_offer.peer_address.use_tor, ) return SentPayment( sent_payment_id=None, diff --git a/squeaknode/db/alembic/versions/231b8b35ed2e_add_use_tor_column_to_all_tables_with_.py b/squeaknode/db/alembic/versions/231b8b35ed2e_add_use_tor_column_to_all_tables_with_.py new file mode 100644 index 00000000..af8e37d6 --- /dev/null +++ b/squeaknode/db/alembic/versions/231b8b35ed2e_add_use_tor_column_to_all_tables_with_.py @@ -0,0 +1,77 @@ +# MIT License +# +# Copyright (c) 2020 Jonathan Zernik +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +"""Add use_tor column to all tables with peer address. + +Revision ID: 231b8b35ed2e +Revises: d7538b753a8a +Create Date: 2021-10-09 20:24:46.594377 + +""" +import sqlalchemy as sa +from alembic import op +from sqlalchemy.sql import expression + + +# revision identifiers, used by Alembic. +revision = '231b8b35ed2e' +down_revision = 'd7538b753a8a' +branch_labels = None +depends_on = None + + +def upgrade(): + with op.batch_alter_table('peer', schema=None) as batch_op: + batch_op.add_column(sa.Column('use_tor', sa.Boolean( + ), nullable=False, server_default=expression.true())) + + with op.batch_alter_table('received_offer', schema=None) as batch_op: + batch_op.add_column(sa.Column('peer_use_tor', sa.Boolean( + ), nullable=False, server_default=expression.true())) + + with op.batch_alter_table('received_payment', schema=None) as batch_op: + batch_op.add_column(sa.Column('peer_use_tor', sa.Boolean( + ), nullable=False, server_default=expression.true())) + + with op.batch_alter_table('sent_offer', schema=None) as batch_op: + batch_op.add_column(sa.Column('peer_use_tor', sa.Boolean( + ), nullable=False, server_default=expression.true())) + + with op.batch_alter_table('sent_payment', schema=None) as batch_op: + batch_op.add_column(sa.Column('peer_use_tor', sa.Boolean( + ), nullable=False, server_default=expression.true())) + + +def downgrade(): + with op.batch_alter_table('sent_payment', schema=None) as batch_op: + batch_op.drop_column('peer_use_tor') + + with op.batch_alter_table('sent_offer', schema=None) as batch_op: + batch_op.drop_column('peer_use_tor') + + with op.batch_alter_table('received_payment', schema=None) as batch_op: + batch_op.drop_column('peer_use_tor') + + with op.batch_alter_table('received_offer', schema=None) as batch_op: + batch_op.drop_column('peer_use_tor') + + with op.batch_alter_table('peer', schema=None) as batch_op: + batch_op.drop_column('use_tor') diff --git a/squeaknode/db/models.py b/squeaknode/db/models.py index 5ba57c89..514cec83 100644 --- a/squeaknode/db/models.py +++ b/squeaknode/db/models.py @@ -95,6 +95,7 @@ class Models: Column("peer_name", String, nullable=False), Column("host", String, nullable=False), Column("port", Integer, nullable=False), + Column("use_tor", Boolean, nullable=False), Column("autoconnect", Boolean, nullable=False), UniqueConstraint('host', 'port', name='uq_peer_host_port'), @@ -120,6 +121,7 @@ class Models: Column("lightning_port", Integer, nullable=False), Column("peer_host", String, nullable=False), Column("peer_port", Integer, nullable=False), + Column("peer_use_tor", Boolean, nullable=False), Column("paid", Boolean, nullable=False, default=False), sqlite_autoincrement=True, ) @@ -131,6 +133,7 @@ class Models: Column("created_time_ms", SLBigInteger, nullable=False), Column("peer_host", String, nullable=False), Column("peer_port", Integer, nullable=False), + Column("peer_use_tor", Boolean, nullable=False), Column("squeak_hash", LargeBinary(32), nullable=False), Column("payment_hash", LargeBinary( 32), unique=True, nullable=False), @@ -157,6 +160,7 @@ class Models: Column("invoice_expiry", Integer, nullable=False), Column("peer_host", String, nullable=False), Column("peer_port", Integer, nullable=False), + Column("peer_use_tor", Boolean, nullable=False), Column("paid", Boolean, nullable=False, default=False), sqlite_autoincrement=True, ) @@ -173,5 +177,6 @@ class Models: Column("settle_index", SLBigInteger, nullable=False), Column("peer_host", String, nullable=False), Column("peer_port", Integer, nullable=False), + Column("peer_use_tor", Boolean, nullable=False), sqlite_autoincrement=True, ) diff --git a/squeaknode/db/squeak_db.py b/squeaknode/db/squeak_db.py index b9754a58..9fb5dfb4 100644 --- a/squeaknode/db/squeak_db.py +++ b/squeaknode/db/squeak_db.py @@ -908,6 +908,7 @@ class SqueakDb: peer_name=squeak_peer.peer_name, host=squeak_peer.address.host, port=squeak_peer.address.port, + use_tor=squeak_peer.address.use_tor, autoconnect=squeak_peer.autoconnect, ) with self.get_connection() as connection: @@ -1004,6 +1005,7 @@ class SqueakDb: lightning_port=received_offer.lightning_address.port, peer_host=received_offer.peer_address.host, peer_port=received_offer.peer_address.port, + peer_use_tor=received_offer.peer_address.use_tor, ) with self.get_connection() as connection: try: @@ -1056,6 +1058,7 @@ class SqueakDb: .where(self.received_offers.c.squeak_hash == squeak_hash) .where(self.received_offers.c.peer_host == peer_address.host) .where(self.received_offers.c.peer_port == peer_address.port) + .where(self.received_offers.c.peer_use_tor == peer_address.use_tor) .where(self.received_offer_is_not_paid) .where(self.received_offer_is_not_expired) ) @@ -1110,6 +1113,7 @@ class SqueakDb: created_time_ms=self.timestamp_now_ms, peer_host=sent_payment.peer_address.host, peer_port=sent_payment.peer_address.port, + peer_use_tor=sent_payment.peer_address.use_tor, squeak_hash=sent_payment.squeak_hash, payment_hash=sent_payment.payment_hash, secret_key=sent_payment.secret_key, @@ -1190,6 +1194,7 @@ class SqueakDb: invoice_expiry=sent_offer.invoice_expiry, peer_host=sent_offer.peer_address.host, peer_port=sent_offer.peer_address.port, + peer_use_tor=sent_offer.peer_address.use_tor, ) with self.get_connection() as connection: res = connection.execute(ins) @@ -1229,6 +1234,7 @@ class SqueakDb: select([self.sent_offers]) .where(self.sent_offers.c.squeak_hash == squeak_hash) .where(self.sent_offers.c.peer_host == peer_address.host) + .where(self.sent_offers.c.peer_use_tor == peer_address.use_tor) .where(self.sent_offer_is_not_paid) .where(self.sent_offer_is_not_expired) ) @@ -1296,6 +1302,7 @@ class SqueakDb: settle_index=received_payment.settle_index, peer_host=received_payment.peer_address.host, peer_port=received_payment.peer_address.port, + peer_use_tor=received_payment.peer_address.use_tor, ) with self.get_connection() as connection: try: @@ -1451,6 +1458,7 @@ class SqueakDb: address=PeerAddress( host=row["host"], port=row["port"], + use_tor=row["use_tor"], ), autoconnect=row["autoconnect"], ) @@ -1474,6 +1482,7 @@ class SqueakDb: peer_address=PeerAddress( host=row["peer_host"], port=row["peer_port"], + use_tor=row["peer_use_tor"], ), ) @@ -1484,6 +1493,7 @@ class SqueakDb: peer_address=PeerAddress( host=row["peer_host"], port=row["peer_port"], + use_tor=row["peer_use_tor"], ), squeak_hash=(row["squeak_hash"]), payment_hash=(row["payment_hash"]), @@ -1507,6 +1517,7 @@ class SqueakDb: peer_address=PeerAddress( host=row["peer_host"], port=row["peer_port"], + use_tor=row["peer_use_tor"], ), ) @@ -1521,6 +1532,7 @@ class SqueakDb: peer_address=PeerAddress( host=row["peer_host"], port=row["peer_port"], + use_tor=row["peer_use_tor"], ), ) diff --git a/squeaknode/network/network_manager.py b/squeaknode/network/network_manager.py index 123fea35..da4126be 100644 --- a/squeaknode/network/network_manager.py +++ b/squeaknode/network/network_manager.py @@ -82,20 +82,16 @@ class NetworkManager(object): def connect_peer_sync(self, peer_address: PeerAddress) -> None: port = peer_address.port or squeak.params.params.DEFAULT_PORT - peer_address = PeerAddress( - host=peer_address.host, - port=port, - ) + peer_address = peer_address._replace( + port=port) if self.connection_manager.has_connection(peer_address): raise Exception("Already connected to: {}".format(peer_address)) self.peer_client.connect_address(peer_address) def connect_peer_async(self, peer_address: PeerAddress) -> None: port = peer_address.port or squeak.params.params.DEFAULT_PORT - peer_address = PeerAddress( - host=peer_address.host, - port=port, - ) + peer_address = peer_address._replace( + port=port) if self.connection_manager.has_connection(peer_address): return self.peer_client.connect_address_async(peer_address) @@ -132,6 +128,7 @@ class NetworkManager(object): return PeerAddress( self.local_ip, self.local_port, + use_tor=False, ) @property @@ -139,6 +136,7 @@ class NetworkManager(object): return PeerAddress( self.external_host or self.local_ip, self.local_port, + use_tor=False, ) def subscribe_connected_peers(self, stopped) -> Iterable[List[Peer]]: diff --git a/squeaknode/network/peer_client.py b/squeaknode/network/peer_client.py index 974cb372..74962624 100644 --- a/squeaknode/network/peer_client.py +++ b/squeaknode/network/peer_client.py @@ -69,9 +69,10 @@ class PeerClient(object): def make_connection(self, address: PeerAddress, result_queue: queue.Queue): logger.info('Conecting to address: {}'.format(address)) try: - peer_socket = self.get_socket() + peer_socket = self.get_socket(address) peer_socket.settimeout(SOCKET_CONNECT_TIMEOUT) - peer_socket.connect(address) + connect_address = (address.host, address.port) + peer_socket.connect(connect_address) peer_socket.setblocking(True) self.handle_connection( peer_socket, @@ -96,8 +97,14 @@ class PeerClient(object): result_queue=result_queue, ) - def get_socket(self): - if self.tor_proxy_ip: + def get_socket(self, address: PeerAddress): + if address.use_tor and self.tor_proxy_ip is None: + raise Exception( + "Unable to connect to tor address without tor proxy ip configured.") + if address.use_tor and self.tor_proxy_port is None: + raise Exception( + "Unable to connect to tor address without tor proxy port configured.") + if address.use_tor: s = socks.socksocket() # Same API as socket.socket in the standard lib s.set_proxy(socks.SOCKS5, self.tor_proxy_ip, self.tor_proxy_port) return s diff --git a/squeaknode/network/peer_server.py b/squeaknode/network/peer_server.py index 207c3047..9408daf9 100644 --- a/squeaknode/network/peer_server.py +++ b/squeaknode/network/peer_server.py @@ -68,6 +68,7 @@ class PeerServer(object): peer_address = PeerAddress( host=host, port=port, + use_tor=False, ) peer_socket.setblocking(True) self.handle_connection( diff --git a/tests/core/test_peers.py b/tests/core/test_peers.py index 601b93fb..bf85c480 100644 --- a/tests/core/test_peers.py +++ b/tests/core/test_peers.py @@ -35,6 +35,16 @@ def peer_address(): yield PeerAddress( host="fake_host", port=8765, + use_tor=False, + ) + + +@pytest.fixture +def peer_address_with_tor(): + yield PeerAddress( + host="fake_host", + port=1234, + use_tor=True, ) @@ -43,6 +53,7 @@ def peer_address_with_no_port(): yield PeerAddress( host="fake_host", port=0, + use_tor=False, ) @@ -59,10 +70,11 @@ def test_create_saved_peer(peer_name, peer_address, default_peer_port): ) assert peer.peer_name == peer_name - assert peer.address == PeerAddress( - host=peer_address.host, - port=peer_address.port, - ) + # assert peer.address == PeerAddress( + # host=peer_address.host, + # port=peer_address.port, + # ) + assert peer.address == peer_address def test_create_saved_peer_empty_name(peer_address, default_peer_port): @@ -82,4 +94,21 @@ def test_create_saved_peer_default_port(peer_name, peer_address_with_no_port, de assert peer.address == PeerAddress( host=peer_address_with_no_port.host, port=default_peer_port, + use_tor=False, ) + + +def test_create_saved_peer_use_tor(peer_name, peer_address_with_tor): + peer = create_saved_peer( + peer_name, + peer_address_with_tor, + default_peer_port, + ) + + assert peer.peer_name == peer_name + # assert peer.address == PeerAddress( + # host=peer_address_with_tor.host, + # port=peer_address_with_tor.port, + # use_tor=peer_address_with_tor.use_tor, + # ) + assert peer.address == peer_address_with_tor diff --git a/tests/network/test_connection_manager.py b/tests/network/test_connection_manager.py index 94b70166..2ccb674b 100644 --- a/tests/network/test_connection_manager.py +++ b/tests/network/test_connection_manager.py @@ -39,6 +39,7 @@ def local_address(): yield PeerAddress( local_ip, local_port, + use_tor=False, ) @@ -61,12 +62,12 @@ def outbound_socket(inbound_socket_and_outbound_socket): @pytest.fixture def inbound_local_address(): - yield PeerAddress('inbound.com', 56789) + yield PeerAddress('inbound.com', 56789, use_tor=False) @pytest.fixture def outbound_local_address(): - yield PeerAddress('outbound.com', 4321) + yield PeerAddress('outbound.com', 4321, use_tor=False) @pytest.fixture diff --git a/tests/node/test_squeak_controller.py b/tests/node/test_squeak_controller.py index b8c54c73..481a2149 100644 --- a/tests/node/test_squeak_controller.py +++ b/tests/node/test_squeak_controller.py @@ -73,12 +73,12 @@ def lightning_host_port(): @pytest.fixture def peer_address(): - return PeerAddress(host="fake_host", port=5678) + return PeerAddress(host="fake_host", port=5678, use_tor=False) @pytest.fixture def peer_address_with_zero(): - return PeerAddress(host="fake_host", port=0) + return PeerAddress(host="fake_host", port=0, use_tor=False) @pytest.fixture @@ -179,6 +179,7 @@ def test_create_peer_default_port(config, squeak_db, squeak_controller, peer_add address=PeerAddress( host=peer_address_with_zero.host, port=squeak.params.params.DEFAULT_PORT, + use_tor=peer_address_with_zero.use_tor, ), autoconnect=False, )