Return core types from peer client (#765)

* Create message module with util functions for peer protocol

* Use message util functions in rpc server servicer
This commit is contained in:
Jonathan Zernik 2021-01-30 19:56:01 -08:00 committed by GitHub
parent 12deeeaaf6
commit f6cd2bc7db
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 80 additions and 97 deletions

View file

@ -0,0 +1,49 @@
import logging
from squeak.core import CheckSqueak
from squeak.core import CSqueak
from proto import squeak_server_pb2
from squeaknode.core.offer import Offer
from squeaknode.core.util import get_hash
logger = logging.getLogger(__name__)
def squeak_to_msg(squeak: CSqueak) -> squeak_server_pb2.Squeak:
return squeak_server_pb2.Squeak(
hash=get_hash(squeak),
serialized_squeak=squeak.serialize(),
)
def squeak_from_msg(squeak_msg: squeak_server_pb2.Squeak) -> CSqueak:
squeak = CSqueak.deserialize(squeak_msg.serialized_squeak)
CheckSqueak(squeak, skipDecryptionCheck=True)
squeak_hash = get_hash(squeak)
if squeak_msg.hash != squeak_hash:
raise Exception("Invalid squeak hash: {}".format(
squeak_hash
))
return squeak
def offer_from_msg(offer_msg: squeak_server_pb2.Offer) -> Offer:
return Offer(
squeak_hash=offer_msg.squeak_hash,
nonce=offer_msg.nonce,
payment_request=offer_msg.payment_request,
host=offer_msg.host,
port=offer_msg.port,
)
def offer_to_msg(offer: Offer) -> squeak_server_pb2.Offer:
return squeak_server_pb2.Offer(
squeak_hash=offer.squeak_hash,
nonce=offer.nonce,
payment_request=offer.payment_request,
host=offer.host,
port=offer.port,
)

View file

@ -3,12 +3,15 @@ from contextlib import contextmanager
from typing import List
import grpc
from squeak.core import CheckSqueak
from squeak.core import CSqueak
from proto import squeak_server_pb2
from proto import squeak_server_pb2_grpc
from squeaknode.core.util import get_hash
from squeaknode.core.offer import Offer
from squeaknode.network.messages import offer_from_msg
from squeaknode.network.messages import squeak_from_msg
from squeaknode.network.messages import squeak_to_msg
logger = logging.getLogger(__name__)
@ -48,42 +51,26 @@ class PeerClient:
)
return lookup_response
def upload_squeak(self, squeak: CSqueak):
squeak_msg = self._build_squeak_msg(squeak)
def upload_squeak(self, squeak: CSqueak) -> None:
squeak_msg = squeak_to_msg(squeak)
self.stub.UploadSqueak(
squeak_server_pb2.UploadSqueakRequest(
squeak=squeak_msg,
)
)
def download_squeak(self, squeak_hash: bytes):
def download_squeak(self, squeak_hash: bytes) -> CSqueak:
get_response = self.stub.DownloadSqueak(
squeak_server_pb2.DownloadSqueakRequest(
hash=squeak_hash,
)
)
get_response_squeak = self._squeak_from_msg(get_response.squeak)
CheckSqueak(get_response_squeak, skipDecryptionCheck=True)
return get_response_squeak
return squeak_from_msg(get_response.squeak)
def download_offer(self, squeak_hash: bytes):
def download_offer(self, squeak_hash: bytes) -> Offer:
download_offer_response = self.stub.DownloadOffer(
squeak_server_pb2.DownloadOfferRequest(
hash=squeak_hash,
)
)
offer_msg = download_offer_response.offer
return offer_msg
def _build_squeak_msg(self, squeak: CSqueak):
return squeak_server_pb2.Squeak(
hash=get_hash(squeak),
serialized_squeak=squeak.serialize(),
)
def _squeak_from_msg(self, squeak_msg: squeak_server_pb2.Squeak):
if not squeak_msg:
return None
if not squeak_msg.serialized_squeak:
return None
return CSqueak.deserialize(squeak_msg.serialized_squeak)
return offer_from_msg(download_offer_response.offer)

View file

@ -2,11 +2,12 @@ import logging
from concurrent import futures
import grpc
from squeak.core import CSqueak
from proto import squeak_server_pb2
from proto import squeak_server_pb2_grpc
from squeaknode.core.util import get_hash
from squeaknode.network.messages import offer_to_msg
from squeaknode.network.messages import squeak_from_msg
from squeaknode.network.messages import squeak_to_msg
from squeaknode.server.util import parse_ip_address
logger = logging.getLogger(__name__)
@ -23,45 +24,22 @@ class SqueakServerServicer(squeak_server_pb2_grpc.SqueakServerServicer):
def UploadSqueak(self, request, context):
squeak_msg = request.squeak
squeak_hash = squeak_msg.hash
squeak = CSqueak.deserialize(squeak_msg.serialized_squeak)
# Check is squeak deserialized correctly
if squeak is None:
context.set_code(grpc.StatusCode.INVALID_ARGUMENT)
return squeak_server_pb2.UploadSqueakReply()
# Check if squeak hash is correct
if get_hash(squeak) != squeak_hash:
context.set_code(grpc.StatusCode.INVALID_ARGUMENT)
return squeak_server_pb2.UploadSqueakReply()
# Check if squeak is unlocked
if not squeak.HasDecryptionKey():
context.set_code(grpc.StatusCode.INVALID_ARGUMENT)
return squeak_server_pb2.UploadSqueakReply()
# Insert the squeak in database.
squeak = squeak_from_msg(squeak_msg)
# Handle the uploaded squeak
self.handler.handle_posted_squeak(squeak)
return squeak_server_pb2.UploadSqueakReply()
def DownloadSqueak(self, request: squeak_server_pb2.DownloadSqueakRequest, context):
squeak_hash = request.hash
# TODO: check if hash is valid
# Basic hash validity check
if len(squeak_hash) != 32:
raise Exception("Invalid squeak hash length.")
squeak = self.handler.handle_get_squeak(squeak_hash)
if squeak is None:
context.set_code(grpc.StatusCode.NOT_FOUND)
context.set_details("Squeak not found.")
return squeak_server_pb2.DownloadSqueakReply(
squeak=None,
)
raise Exception("Squeak not found.")
squeak_msg = squeak_to_msg(squeak)
return squeak_server_pb2.DownloadSqueakReply(
squeak=squeak_server_pb2.Squeak(
hash=get_hash(squeak),
serialized_squeak=squeak.serialize(),
)
squeak=squeak_msg,
)
def LookupSqueaksToDownload(self, request, context):
@ -75,26 +53,13 @@ class SqueakServerServicer(squeak_server_pb2_grpc.SqueakServerServicer):
# TODO: check if hash is valid
client_addr = context.peer()
ip_addr = parse_ip_address(client_addr)
buy_response = self.handler.handle_get_offer(squeak_hash, ip_addr)
if buy_response is None:
context.set_code(grpc.StatusCode.NOT_FOUND)
context.set_details("Offer not found.")
return squeak_server_pb2.DownloadOfferReply(
offer=None,
)
logger.info("Sending buy offer: {}".format(buy_response))
offer = self.handler.handle_get_offer(squeak_hash, ip_addr)
if offer is None:
raise Exception("Offer not found.")
logger.info("Sending offer: {}".format(offer))
offer_msg = offer_to_msg(offer)
return squeak_server_pb2.DownloadOfferReply(
offer=squeak_server_pb2.Offer(
squeak_hash=buy_response.squeak_hash,
nonce=buy_response.nonce,
payment_request=buy_response.payment_request,
host=buy_response.host,
port=buy_response.port,
),
offer=offer_msg,
)
def serve(self):

View file

@ -4,7 +4,6 @@ from typing import Optional
from squeaknode.core.received_offer_with_peer import ReceivedOfferWithPeer
from squeaknode.network.peer_client import PeerClient
from squeaknode.sync.util import parse_buy_offer
logger = logging.getLogger(__name__)
@ -138,10 +137,10 @@ class PeerConnection:
def _download_offer(self, squeak_hash: bytes):
squeak = self.squeak_controller.get_squeak(squeak_hash)
offer_msg = self.peer_client.download_offer(squeak_hash)
buy_offer = parse_buy_offer(offer_msg)
offer = self.peer_client.download_offer(squeak_hash)
# buy_offer = parse_buy_offer(offer_msg)
decoded_offer = self.squeak_controller.get_offer(
squeak, buy_offer, self.peer)
squeak, offer, self.peer)
self.squeak_controller.save_offer(decoded_offer)
logger.info("Downloaded offer for squeak {} from peer {}".format(
squeak_hash.hex(), self.peer

View file

@ -1,17 +0,0 @@
import logging
from proto import squeak_server_pb2
from squeaknode.core.offer import Offer
logger = logging.getLogger(__name__)
def parse_buy_offer(buy_offer_msg: squeak_server_pb2.Offer) -> Offer:
return Offer(
squeak_hash=buy_offer_msg.squeak_hash,
nonce=buy_offer_msg.nonce,
payment_request=buy_offer_msg.payment_request,
host=buy_offer_msg.host,
port=buy_offer_msg.port,
)