Make peer client connect with tor (#2018)

This commit is contained in:
Jonathan Zernik 2022-03-25 23:12:43 -07:00 committed by GitHub
parent a87b3d6ad7
commit 8a89dbfa10
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 93 additions and 20 deletions

View file

@ -11,7 +11,7 @@ protobuf==3.17.3
PySocks==1.7.1
python-bitcoinlib==0.11.0
pyzmq==22.3.0
requests==2.26.0
requests[socks]==2.26.0
SQLAlchemy==1.4.25
squeaklib==0.11.0
typed-config==0.2.5

View file

@ -20,6 +20,7 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
import logging
from typing import Optional
from squeak.core.keys import SqueakPublicKey
@ -35,8 +36,15 @@ DOWNLOAD_TIMEOUT_S = 10
class NetworkController:
def __init__(self, squeak_store: SqueakStore):
def __init__(
self,
squeak_store: SqueakStore,
proxy_host: Optional[str],
proxy_port: Optional[int],
):
self.squeak_store = squeak_store
self.proxy_host = proxy_host
self.proxy_port = proxy_port
def download_timeline_async(
self,
@ -50,6 +58,8 @@ class NetworkController:
downloader = RangeDownloader(
peer,
self.squeak_store,
self.proxy_host,
self.proxy_port,
min_block,
max_block,
followed_public_keys,
@ -64,6 +74,8 @@ class NetworkController:
downloader = RangeDownloader(
peer,
self.squeak_store,
self.proxy_host,
self.proxy_port,
min_block,
max_block,
[pubkey],
@ -76,6 +88,8 @@ class NetworkController:
downloader = SingleDownloader(
peer,
self.squeak_store,
self.proxy_host,
self.proxy_port,
squeak_hash,
)
downloader.download_async()

View file

@ -28,6 +28,7 @@ from squeak.core import CSqueak
from squeak.core.keys import SqueakPublicKey
from squeaknode.core.offer import Offer
from squeaknode.core.peer_address import Network
from squeaknode.core.squeak_peer import SqueakPeer
logger = logging.getLogger(__name__)
@ -38,9 +39,23 @@ REQUEST_TIMEOUT_S = 10
class PeerClient:
def __init__(self, peer: SqueakPeer):
def __init__(
self,
peer: SqueakPeer,
proxy_host: Optional[str],
proxy_port: Optional[int],
):
self.peer = peer
self.proxy_host = proxy_host
self.proxy_port = proxy_port
self.base_url = f"http://{peer.address.host}:{peer.address.port}"
self.proxies = {}
if peer.address.network == Network.TORV3 and \
proxy_host is not None and \
proxy_port is not None:
self.proxies = {
"http": f'socks5://{proxy_host}:{proxy_port}',
}
def lookup(
self,
@ -61,6 +76,7 @@ class PeerClient:
r = requests.get( # type: ignore
url,
params=payload, # type: ignore
proxies=self.proxies,
timeout=REQUEST_TIMEOUT_S,
)
squeak_hashes_str = r.json()
@ -72,7 +88,11 @@ class PeerClient:
def get_squeak(self, squeak_hash: bytes) -> Optional[CSqueak]:
squeak_hash_str = squeak_hash.hex()
url = f"{self.base_url}/squeak/{squeak_hash_str}"
r = requests.get(url, timeout=REQUEST_TIMEOUT_S)
r = requests.get(
url,
proxies=self.proxies,
timeout=REQUEST_TIMEOUT_S,
)
if r.status_code != requests.codes.ok:
return None
squeak_bytes = r.content
@ -81,7 +101,11 @@ class PeerClient:
def get_secret_key(self, squeak_hash: bytes) -> Optional[bytes]:
squeak_hash_str = squeak_hash.hex()
url = f"{self.base_url}/secretkey/{squeak_hash_str}"
r = requests.get(url, timeout=REQUEST_TIMEOUT_S)
r = requests.get(
url,
proxies=self.proxies,
timeout=REQUEST_TIMEOUT_S,
)
if r.status_code != requests.codes.ok:
return None
secret_key = r.content
@ -90,7 +114,11 @@ class PeerClient:
def get_offer(self, squeak_hash: bytes) -> Optional[Offer]:
squeak_hash_str = squeak_hash.hex()
url = f"{self.base_url}/offer/{squeak_hash_str}"
r = requests.get(url, timeout=REQUEST_TIMEOUT_S)
r = requests.get(
url,
proxies=self.proxies,
timeout=REQUEST_TIMEOUT_S,
)
if r.status_code != requests.codes.ok:
return None
offer_json = r.json()

View file

@ -24,6 +24,7 @@ import threading
from abc import ABC
from abc import abstractmethod
from typing import List
from typing import Optional
from squeak.core import CSqueak
from squeak.core.keys import SqueakPublicKey
@ -41,9 +42,17 @@ DOWNLOAD_TIMEOUT_S = 10
class PeerDownloader(ABC):
def __init__(self, peer: SqueakPeer, squeak_store: SqueakStore):
def __init__(
self,
peer: SqueakPeer,
squeak_store: SqueakStore,
proxy_host: Optional[str],
proxy_port: Optional[int],
):
self.peer = peer
self.client = PeerClient(peer)
self.proxy_host = proxy_host
self.proxy_port = proxy_port
self.client = PeerClient(peer, proxy_host, proxy_port)
self.squeak_store = squeak_store
@abstractmethod
@ -114,11 +123,13 @@ class RangeDownloader(PeerDownloader):
self,
peer: SqueakPeer,
squeak_store: SqueakStore,
proxy_host: Optional[str],
proxy_port: Optional[int],
min_block: int,
max_block: int,
pubkeys: List[SqueakPublicKey],
):
super().__init__(peer, squeak_store)
super().__init__(peer, squeak_store, proxy_host, proxy_port)
self.min_block = min_block
self.max_block = max_block
self.pubkeys = pubkeys
@ -142,9 +153,11 @@ class SingleDownloader(PeerDownloader):
self,
peer: SqueakPeer,
squeak_store: SqueakStore,
proxy_host: Optional[str],
proxy_port: Optional[int],
squeak_hash: bytes,
):
super().__init__(peer, squeak_store)
super().__init__(peer, squeak_store, proxy_host, proxy_port)
self.squeak_hash = squeak_hash
def get_hashes(self) -> List[bytes]:

View file

@ -28,7 +28,6 @@ from squeak.core import CSqueak
from squeak.core.keys import SqueakPrivateKey
from squeak.core.keys import SqueakPublicKey
from squeaknode.client.network_controller import NetworkController
from squeaknode.core.download_result import DownloadResult
from squeaknode.core.lightning_address import LightningAddressHostPort
from squeaknode.core.offer import Offer
@ -63,6 +62,7 @@ class SqueakController:
squeak_core: SqueakCore,
payment_processor,
tweet_forwarder,
network_controller,
node_settings,
config,
default_port,
@ -71,6 +71,7 @@ class SqueakController:
self.squeak_core = squeak_core
self.payment_processor = payment_processor
self.tweet_forwarder = tweet_forwarder
self.network_controller = network_controller
self.node_settings = node_settings
self.config = config
self.default_port = default_port
@ -296,8 +297,7 @@ class SqueakController:
return self.squeak_store.get_squeak_entry(squeak_hash)
def download_single_squeak(self, squeak_hash: bytes) -> DownloadResult:
network_controller = NetworkController(self.squeak_store)
network_controller.download_single_squeak(squeak_hash)
self.network_controller.download_single_squeak(squeak_hash)
return DownloadResult(1, 1, 0, 9999)
def get_timeline_squeak_entries(
@ -307,8 +307,7 @@ class SqueakController:
) -> List[SqueakEntry]:
# TODO: remove this temporary hack, after converting this to websockets.
# logger.info('Start downloading timeline...')
# network_controller = NetworkController(self.squeak_store)
# network_controller.download_timeline()
# self.network_controller.download_timeline()
# logger.info('Finished downloading timeline.')
return self.squeak_store.get_timeline_squeak_entries(limit, last_entry)
@ -341,8 +340,7 @@ class SqueakController:
) -> List[SqueakEntry]:
# TODO: remove this temporary hack, after converting this to websockets.
logger.info('Start downloading pubkey squeaks...')
network_controller = NetworkController(self.squeak_store)
network_controller.download_pubkey_squeaks_async(public_key)
self.network_controller.download_pubkey_squeaks_async(public_key)
logger.info('Finished downloading pubkey squeaks.')
return self.squeak_store.get_squeak_entries_for_public_key(
public_key,

View file

@ -32,15 +32,14 @@ class SqueakDownloadWorker(PeriodicWorker):
def __init__(
self,
squeak_store: SqueakStore,
network_controller: NetworkController,
download_timeline_interval_s: int,
interest_block_interval: int,
):
self.squeak_store = squeak_store
self.download_timeline_interval_s = download_timeline_interval_s
self.interest_block_interval = interest_block_interval
self.network_controller = NetworkController(
self.squeak_store,
)
self.network_controller = network_controller
def work_fn(self):
self.network_controller.download_timeline_async(

View file

@ -28,6 +28,7 @@ from squeaknode.admin.squeak_admin_server_handler import SqueakAdminServerHandle
from squeaknode.admin.squeak_admin_server_servicer import SqueakAdminServerServicer
from squeaknode.admin.webapp.app import SqueakAdminWebServer
from squeaknode.bitcoin.bitcoin_core_client import BitcoinCoreClient
from squeaknode.client.network_controller import NetworkController
from squeaknode.config.config import SqueaknodeConfig
from squeaknode.core.squeak_core import SqueakCore
from squeaknode.db.db_engine import get_connection_string
@ -63,6 +64,7 @@ class SqueakNode:
self.create_squeak_store()
self.create_payment_processor()
self.create_twitter_forwarder()
self.create_network_controller()
self.create_squeak_controller()
self.create_peer_handler()
@ -164,12 +166,20 @@ class SqueakNode:
self.config.twitter.forward_tweets_retry_s,
)
def create_network_controller(self):
self.network_controller = NetworkController(
self.squeak_store,
self.config.tor.proxy_ip,
self.config.tor.proxy_port,
)
def create_squeak_controller(self):
self.squeak_controller = SqueakController(
self.squeak_store,
self.squeak_core,
self.payment_processor,
self.twitter_forwarder,
self.network_controller,
self.node_settings,
self.config,
squeak.params.params.DEFAULT_PORT,
@ -228,6 +238,7 @@ class SqueakNode:
def create_squeak_download_worker(self):
self.squeak_download_worker = SqueakDownloadWorker(
self.squeak_store,
self.network_controller,
self.config.node.peer_download_interval_s,
self.config.node.interest_block_interval,
)

View file

@ -22,6 +22,7 @@
import mock
import pytest
from squeaknode.client.network_controller import NetworkController
from squeaknode.config.config import SqueaknodeConfig
from squeaknode.core.lightning_address import LightningAddressHostPort
from squeaknode.core.peer_address import Network
@ -108,12 +109,18 @@ def twitter_forwarder():
return mock.Mock(spec=TwitterForwarder)
@pytest.fixture
def network_controller():
return mock.Mock(spec=NetworkController)
@pytest.fixture
def squeak_controller(
squeak_store,
squeak_core,
payment_processor,
twitter_forwarder,
network_controller,
node_settings,
config,
default_peer_port,
@ -123,6 +130,7 @@ def squeak_controller(
squeak_core,
payment_processor,
twitter_forwarder,
network_controller,
node_settings,
config,
default_peer_port,
@ -135,6 +143,7 @@ def regtest_squeak_controller(
squeak_core,
payment_processor,
twitter_forwarder,
network_controller,
node_settings,
regtest_config,
default_peer_port,
@ -144,6 +153,7 @@ def regtest_squeak_controller(
squeak_core,
payment_processor,
twitter_forwarder,
network_controller,
node_settings,
regtest_config,
default_peer_port,