diff --git a/squeaknode/db/squeak_db.py b/squeaknode/db/squeak_db.py index f9f3809e..bbee7325 100644 --- a/squeaknode/db/squeak_db.py +++ b/squeaknode/db/squeak_db.py @@ -792,6 +792,35 @@ class SqueakDb: offer_with_peer = self._parse_received_offer_with_peer(row) return offer_with_peer + def get_received_offer_for_squeak_and_peer( + self, + squeak_hash: bytes, + peer_address: PeerAddress, + ) -> Optional[ReceivedOfferWithPeer]: + """ Get offer with peer for a given peer address and squeak hash . """ + s = ( + select([self.received_offers, self.peers]) + .select_from( + self.received_offers.outerjoin( + self.peers, + self.peers.c.host == self.received_offers.c.peer_host, + self.peers.c.port == self.received_offers.c.peer_port, + ) + ) + .where(self.received_offers.c.squeak_hash == squeak_hash.hex()) + .where(self.received_offers.c.peer_host == peer_address.host) + .where(self.received_offers.c.peer_port == peer_address.port) + .where(self.received_offer_is_not_paid) + .where(self.received_offer_is_not_expired) + ) + with self.get_connection() as connection: + result = connection.execute(s) + row = result.fetchone() + if row is None: + return None + offer_with_peer = self._parse_received_offer_with_peer(row) + return offer_with_peer + def delete_expired_received_offers(self): """ Delete all expired offers. """ s = self.received_offers.delete().where( diff --git a/squeaknode/node/squeak_controller.py b/squeaknode/node/squeak_controller.py index 8e4fe6a6..fe161c00 100644 --- a/squeaknode/node/squeak_controller.py +++ b/squeaknode/node/squeak_controller.py @@ -1,6 +1,7 @@ import logging import threading from typing import List +from typing import Optional from squeak.core import CheckSqueak from squeak.core import CSqueak @@ -338,6 +339,16 @@ class SqueakController: def get_received_offers_with_peer(self, squeak_hash: bytes) -> List[ReceivedOfferWithPeer]: return self.squeak_db.get_received_offers_with_peer(squeak_hash) + def get_received_offer_for_squeak_and_peer( + self, + squeak_hash: bytes, + peer_addresss: PeerAddress, + ) -> Optional[ReceivedOfferWithPeer]: + return self.squeak_db.get_received_offer_for_squeak_and_peer( + squeak_hash, + peer_addresss, + ) + def get_buy_offer_with_peer(self, received_offer_id: int) -> ReceivedOfferWithPeer: received_offer_with_peer = self.squeak_db.get_offer_with_peer( received_offer_id) diff --git a/squeaknode/sync/peer_connection.py b/squeaknode/sync/peer_connection.py index 1269ef6a..709a59cf 100644 --- a/squeaknode/sync/peer_connection.py +++ b/squeaknode/sync/peer_connection.py @@ -121,13 +121,10 @@ class PeerConnection: self._upload_squeak(squeak_hash) def _get_saved_offer(self, squeak_hash: bytes) -> Optional[ReceivedOfferWithPeer]: - offers = self.squeak_controller.get_received_offers_with_peer( - squeak_hash) - for offer_with_peer in offers: - if offer_with_peer.received_offer.peer_address.host == self.peer_address.host \ - and offer_with_peer.received_offer.peer_address.port == self.peer_address.port: - return offer_with_peer - return None + return self.squeak_controller.get_received_offer_for_squeak_and_peer( + squeak_hash, + self.peer_address, + ) def _download_squeak(self, squeak_hash: bytes): squeak = self.peer_client.download_squeak(squeak_hash)