Esempio n. 1
0
 def forward_secret_key(self, squeak):
     logger.debug("Forward new secret key for hash: {!r}".format(
         get_hash(squeak).hex(), ))
     for peer in self.network_manager.get_connected_peers():
         if peer.is_remote_subscribed(squeak):
             logger.debug("Forwarding to peer: {}".format(peer, ))
             squeak_hash = get_hash(squeak)
             inv = CInv(type=MSG_SECRET_KEY, hash=squeak_hash)
             inv_msg = msg_inv(inv=[inv])
             peer.send_msg(inv_msg)
     logger.debug("Finished checking peers to forward.")
Esempio n. 2
0
 def get_offer_reply(self, squeak: CSqueak, peer_address: PeerAddress,
                     price_msat: int) -> Optional[OfferReply]:
     sent_offer = self.get_sent_offer_for_peer(
         squeak,
         peer_address,
         price_msat,
     )
     if sent_offer is None:
         return None
     lnd_external_address: Optional[LightningAddressHostPort] = None
     if self.config.lnd.external_host:
         lnd_external_address = LightningAddressHostPort(
             host=self.config.lnd.external_host,
             port=self.config.lnd.port,
         )
     try:
         offer = self.squeak_core.package_offer(
             sent_offer,
             lnd_external_address,
         )
         return OfferReply(
             squeak_hash=get_hash(squeak),
             offer=offer,
         )
     except Exception:
         return None
Esempio n. 3
0
 def get_sent_offer_for_peer(self, squeak: CSqueak,
                             peer_address: PeerAddress,
                             price_msat: int) -> Optional[SentOffer]:
     squeak_hash = get_hash(squeak)
     # Check if there is an existing offer for the hash/peer_address combination
     sent_offer = self.squeak_db.get_sent_offer_by_squeak_hash_and_peer(
         squeak_hash,
         peer_address,
     )
     if sent_offer:
         return sent_offer
     secret_key = self.get_squeak_secret_key(squeak_hash)
     if squeak is None or secret_key is None:
         return None
     try:
         sent_offer = self.squeak_core.create_offer(
             squeak,
             secret_key,
             peer_address,
             price_msat,
         )
     except Exception:
         logger.exception("Failed to create offer.")
         return None
     self.squeak_db.insert_sent_offer(sent_offer)
     return sent_offer
Esempio n. 4
0
    def download_squeak(
        self,
        squeak_hash: bytes,
        min_block: Optional[int] = None,
        max_block: Optional[int] = None,
        pubkeys: Optional[List[SqueakPublicKey]] = None,
    ) -> None:
        # Download the squeak if not already owned.
        if self.squeak_store.get_squeak(squeak_hash):
            raise Exception('Squeak already saved.')

        # Download the squeak if not already owned.
        squeak = self.client.get_squeak(squeak_hash)

        # Check if the squeak is valid.
        if not squeak:
            raise Exception('Squeak not found.')
        if get_hash(squeak) != squeak_hash:
            raise Exception('Squeak has wrong hash.')
        if min_block and squeak.nBlockHeight < min_block:
            raise Exception('Squeak has block height below minimum.')
        if max_block and squeak.nBlockHeight > max_block:
            raise Exception('Squeak has block height above minimum.')
        if pubkeys and squeak.GetPubKey() not in pubkeys:
            raise Exception('Squeak has wronge pubkey.')

        # Save the squeak.
        self.squeak_store.save_squeak(squeak)
Esempio n. 5
0
 def handle_new_squeaks(self):
     logger.debug("Starting UpdateSubscribedSqueaksWorker...")
     for squeak in self.squeak_controller.subscribe_new_squeaks(
             self.stopped, ):
         logger.debug("Handling new squeak: {!r}".format(
             get_hash(squeak).hex(), ))
         # self.forward_squeak(squeak)
         self.squeak_controller.forward_squeak(squeak)
Esempio n. 6
0
    def unpack_offer(
        self,
        squeak: CSqueak,
        offer: Offer,
        peer_address: PeerAddress,
        check_payment_point: bool = False,
    ) -> ReceivedOffer:
        """Get the offer details from the message that the buyer
        receives from the seller.

        Args:
            squeak: The squeak that will be unlocked upon payment.
            offer: The offer details received from the seller.
            peer: The peer that sent the offer.

        Returns:
            ReceivedOffer: A record of the details of the offer for the buyer.
        """
        # Get the squeak hash
        squeak_hash = get_hash(squeak)
        # Check if squeak hash matches squeak_hash in buy_offer.
        if squeak_hash != offer.squeak_hash:
            raise Exception(
                "Squeak hash in offer {!r} does not match squeak hash {!r}.".
                format(offer.squeak_hash, squeak_hash))
        # Decode the payment request
        pay_req = self.lightning_client.decode_pay_req(offer.payment_request)
        squeak_payment_point = squeak.paymentPoint
        payment_hash = pay_req.payment_hash
        price_msat = pay_req.num_msat
        destination = pay_req.destination
        invoice_timestamp = pay_req.timestamp
        invoice_expiry = pay_req.expiry
        lightning_address = LightningAddressHostPort(
            host=offer.host or peer_address.host,
            port=offer.port,
        )
        payment_point = pay_req.payment_point
        expected_payment_point = squeak.paymentPoint
        if check_payment_point:
            if payment_point != expected_payment_point:
                raise Exception("Invalid payment point.")
        return ReceivedOffer(
            received_offer_id=None,
            squeak_hash=squeak_hash,
            price_msat=price_msat,
            payment_hash=payment_hash,
            nonce=offer.nonce,
            payment_point=squeak_payment_point,
            invoice_timestamp=invoice_timestamp,
            invoice_expiry=invoice_expiry,
            payment_request=offer.payment_request,
            destination=destination,
            lightning_address=lightning_address,
            peer_address=peer_address,
            paid=False,
        )
Esempio n. 7
0
    def create_offer(
        self,
        squeak: CSqueak,
        secret_key: bytes,
        peer_address: PeerAddress,
        price_msat: int,
        nonce: bytes = None,
    ) -> SentOffer:
        """Creates an offer to sell a squeak key to another node.

        Args:
            squeak: The squeak to be sold.
            secret_key: The secret key to the squeak.
            peer_address: The address of the buyer.
            price_msat: The price in msats.

        Returns:
            SentOffer: A record of the details of the offer for the seller.
        """
        # Get the squeak hash
        squeak_hash = get_hash(squeak)
        # Generate a new random nonce
        if nonce is None:
            nonce = generate_tweak()
        # Calculate the preimage
        preimage = add_tweak(secret_key, nonce)
        # Create the lightning invoice
        invoice = self.lightning_client.create_invoice(preimage, price_msat)
        return SentOffer(
            sent_offer_id=None,
            squeak_hash=squeak_hash,
            payment_hash=invoice.r_hash,
            nonce=nonce,
            price_msat=price_msat,
            payment_request=invoice.payment_request,
            invoice_time=invoice.creation_date,
            invoice_expiry=invoice.expiry,
            peer_address=peer_address,
            paid=False,
        )
Esempio n. 8
0
 def subscribe_squeak_entries(self, stopped: threading.Event):
     for item in self.new_squeak_listener.yield_items(stopped):
         squeak_hash = get_hash(item)
         yield self.get_squeak_entry(squeak_hash)
Esempio n. 9
0
 def subscribe_timeline_squeak_entries(self, stopped: threading.Event):
     for item in self.new_squeak_listener.yield_items(stopped):
         followed_addresses = self.get_followed_addresses()
         if str(item.GetAddress()) in set(followed_addresses):
             squeak_hash = get_hash(item)
             yield self.get_squeak_entry(squeak_hash)
Esempio n. 10
0
 def subscribe_squeak_address_entries(self, squeak_address: str,
                                      stopped: threading.Event):
     for item in self.new_squeak_listener.yield_items(stopped):
         if squeak_address == str(item.GetAddress()):
             squeak_hash = get_hash(item)
             yield self.get_squeak_entry(squeak_hash)
Esempio n. 11
0
 def subscribe_squeak_ancestor_entries(self, squeak_hash: bytes,
                                       stopped: threading.Event):
     for item in self.new_squeak_listener.yield_items(stopped):
         if squeak_hash == get_hash(item):
             yield self.get_ancestor_squeak_entries(squeak_hash)
Esempio n. 12
0
def squeak_hash(squeak):
    yield get_hash(squeak)
Esempio n. 13
0
 def subscribe_squeak_reply_entries(self, squeak_hash: bytes,
                                    stopped: threading.Event):
     for item in self.new_squeak_listener.yield_items(stopped):
         if squeak_hash == item.hashReplySqk:
             reply_hash = get_hash(item)
             yield self.get_squeak_entry(reply_hash)
Esempio n. 14
0
def reply_squeak_hash(reply_squeak):
    yield get_hash(reply_squeak)
Esempio n. 15
0
 def subscribe_squeak_public_key_entries(self, public_key: SqueakPublicKey, stopped: threading.Event):
     for item in self.squeak_store.subscribe_new_squeaks(stopped):
         if public_key == item.GetPubKey():
             squeak_hash = get_hash(item)
             yield self.get_squeak_entry(squeak_hash)
Esempio n. 16
0
 def subscribe_squeak_entries(self, stopped: threading.Event):
     for item in self.squeak_store.subscribe_new_squeaks(stopped):
         squeak_hash = get_hash(item)
         yield self.get_squeak_entry(squeak_hash)
Esempio n. 17
0
 def subscribe_timeline_squeak_entries(self, stopped: threading.Event):
     for item in self.squeak_store.subscribe_new_squeaks(stopped):
         followed_public_keys = self.squeak_store.get_followed_public_keys()
         if item.GetPubKey() in set(followed_public_keys):
             squeak_hash = get_hash(item)
             yield self.get_squeak_entry(squeak_hash)
Esempio n. 18
0
def test_get_hash(squeak, squeak_hash):
    expected_hash = squeak.GetHash()[::-1]

    assert get_hash(squeak) == expected_hash
Esempio n. 19
0
 def matches_requested_squeak_hash(self, squeak_hash: bytes) -> bool:
     return squeak_hash == get_hash(self.squeak)
Esempio n. 20
0
def resqueak_hash(resqueak):
    yield get_hash(resqueak)