diff --git a/squeaknode/core/squeak_core.py b/squeaknode/core/squeak_core.py index 41ee4538..76ce69a1 100644 --- a/squeaknode/core/squeak_core.py +++ b/squeaknode/core/squeak_core.py @@ -6,6 +6,7 @@ from typing import NamedTuple from typing import Optional import grpc +from bitcoin.core import CBlockHeader from squeak.core import CheckSqueak from squeak.core import CSqueak from squeak.core import MakeSqueakFromStr @@ -22,7 +23,6 @@ from squeaknode.core.received_offer import ReceivedOffer from squeaknode.core.received_payment import ReceivedPayment from squeaknode.core.sent_offer import SentOffer from squeaknode.core.sent_payment import SentPayment -from squeaknode.core.squeak_entry import SqueakEntry from squeaknode.core.squeak_profile import SqueakProfile from squeaknode.core.util import add_tweak from squeaknode.core.util import generate_tweak @@ -49,7 +49,7 @@ class SqueakCore: self.bitcoin_client = bitcoin_client self.lightning_client = lightning_client - def make_squeak(self, signing_profile: SqueakProfile, content_str: str, replyto_hash: Optional[bytes] = None) -> SqueakEntry: + def make_squeak(self, signing_profile: SqueakProfile, content_str: str, replyto_hash: Optional[bytes] = None) -> CSqueak: """Create a new squeak. Args: @@ -58,7 +58,7 @@ class SqueakCore: replyto_hash: The hash of the squeak to which this one is replying. Returns: - SqueakEntry: containing the squeak together with its block header. + CSqueak: the squeak that was created. Raises: Exception: If the profile does not have a signing key. @@ -71,7 +71,7 @@ class SqueakCore: block_height = block_info.block_height block_hash = block_info.block_hash timestamp = int(time.time()) - squeak = MakeSqueakFromStr( + return MakeSqueakFromStr( signing_key, content_str, block_height, @@ -79,21 +79,16 @@ class SqueakCore: timestamp, replyto_hash, ) - block_header = parse_block_header(block_info.block_header) - return SqueakEntry( - squeak=squeak, - block_header=block_header, - ) - def validate_squeak(self, squeak: CSqueak) -> SqueakEntry: + def get_block_header(self, squeak: CSqueak) -> CBlockHeader: """Checks if the embedded block hash in the squeak is valid for its - block height. + block height and return the associtated block header. Args: squeak: The squeak to be validated. Returns: - SqueakEntry: containing the squeak together with its block header. + CBlockHeader: the block header associated with the given squeak. Raises: Exception: If the block hash is not valid. @@ -103,27 +98,25 @@ class SqueakCore: squeak.nBlockHeight) if squeak.hashBlock != block_info.block_hash: raise Exception("Block hash incorrect.") - block_header = parse_block_header(block_info.block_header) - return SqueakEntry( - squeak=squeak, - block_header=block_header, - ) + return parse_block_header(block_info.block_header) - def validate_decryption_key(self, squeak: CSqueak, secret_key: bytes) -> None: - """Checks if the secret key is valid for the given squeak. + def get_decrypted_content(self, squeak: CSqueak, secret_key: bytes) -> bytes: + """Checks if the secret key is valid for the given squeak and returns + the decrypted content. Args: squeak: The squeak to be validated. secret_key: The secret key. Returns: - None: + bytes: the decrypted content Raises: Exception: If the secret key is not valid. """ squeak.SetDecryptionKey(secret_key) CheckSqueak(squeak) + return squeak.GetDecryptedContent() def get_best_block_height(self) -> int: """Get the current height of the latest block in the blockchain. diff --git a/squeaknode/node/squeak_controller.py b/squeaknode/node/squeak_controller.py index 83122f48..73f23274 100644 --- a/squeaknode/node/squeak_controller.py +++ b/squeaknode/node/squeak_controller.py @@ -24,6 +24,7 @@ from squeaknode.core.received_payment_summary import ReceivedPaymentSummary from squeaknode.core.sent_offer import SentOffer from squeaknode.core.sent_payment import SentPayment from squeaknode.core.sent_payment_summary import SentPaymentSummary +from squeaknode.core.squeak_entry import SqueakEntry from squeaknode.core.squeak_entry_with_profile import SqueakEntryWithProfile from squeaknode.core.squeak_peer import SqueakPeer from squeaknode.core.squeak_profile import SqueakProfile @@ -68,8 +69,13 @@ class SqueakController: Raises: Exception: If squeak fails to save. """ - # Check if squeak is valid. - squeak_entry = self.squeak_core.validate_squeak(squeak) + # Get the block header for the squeak. + block_header = self.squeak_core.get_block_header(squeak) + squeak_entry = SqueakEntry( + squeak=squeak, + block_header=block_header, + ) + # Check if limit exceeded. if self.get_number_of_squeaks() >= self.config.core.max_squeaks: raise Exception("Exceeded max number of squeaks.") @@ -88,12 +94,41 @@ class SqueakController: self.new_squeak_listener.handle_new_squeak(squeak) return inserted_squeak_hash + def unlock_squeak(self, squeak_hash: bytes, secret_key: bytes): + squeak_entry = self.squeak_db.get_squeak_entry(squeak_hash) + squeak = squeak_entry.squeak + decrypted_content = self.squeak_core.get_decrypted_content( + squeak, + secret_key, + ) + # TODO: set decryption key should also take decrypted content. + self.squeak_db.set_squeak_decryption_key( + squeak_hash, + secret_key, + ) + logger.info("Unlocked squeak: {} with content: {}".format( + squeak_hash.hex(), + decrypted_content, + )) + + def make_squeak(self, profile_id: int, content_str: str, replyto_hash: bytes) -> bytes: + squeak_profile = self.squeak_db.get_profile(profile_id) + squeak = self.squeak_core.make_squeak( + squeak_profile, content_str, replyto_hash) + return self.save_squeak(squeak) + def get_squeak(self, squeak_hash: bytes) -> Optional[CSqueak]: squeak_entry = self.squeak_db.get_squeak_entry(squeak_hash) if squeak_entry is None: return None return squeak_entry.squeak + def delete_squeak(self, squeak_hash: bytes) -> None: + num_deleted_offers = self.squeak_db.delete_offers_for_squeak( + squeak_hash) + logger.info("Deleted number of offers : {}".format(num_deleted_offers)) + self.squeak_db.delete_squeak(squeak_hash) + def get_buy_offer(self, squeak_hash: bytes, peer_address: PeerAddress) -> Offer: # Check if there is an existing offer for the hash/peer_address combination sent_offer = self.get_saved_sent_offer(squeak_hash, peer_address) @@ -227,18 +262,6 @@ class SqueakController: )) return profile.private_key - def make_squeak(self, profile_id: int, content_str: str, replyto_hash: bytes) -> bytes: - squeak_profile = self.squeak_db.get_profile(profile_id) - squeak_entry = self.squeak_core.make_squeak( - squeak_profile, content_str, replyto_hash) - return self.save_squeak(squeak_entry.squeak) - - def delete_squeak(self, squeak_hash: bytes) -> None: - num_deleted_offers = self.squeak_db.delete_offers_for_squeak( - squeak_hash) - logger.info("Deleted number of offers : {}".format(num_deleted_offers)) - self.squeak_db.delete_squeak(squeak_hash) - def create_peer(self, peer_name: str, peer_address: PeerAddress): if len(peer_name) == 0: raise Exception( @@ -316,21 +339,6 @@ class SqueakController: ) return sent_payment_id - def unlock_squeak(self, squeak_hash: bytes, secret_key: bytes): - squeak_entry = self.squeak_db.get_squeak_entry(squeak_hash) - squeak = squeak_entry.squeak - self.squeak_core.validate_decryption_key( - squeak, - secret_key, - ) - self.squeak_db.set_squeak_decryption_key( - squeak_hash, - secret_key, - ) - logger.info("Unlocked squeak: {}".format( - squeak_hash.hex(), - )) - def get_sent_payments(self) -> List[SentPayment]: return self.squeak_db.get_sent_payments() diff --git a/tests/core/test_squeak_core.py b/tests/core/test_squeak_core.py index cbe2bb7f..30237157 100644 --- a/tests/core/test_squeak_core.py +++ b/tests/core/test_squeak_core.py @@ -80,13 +80,9 @@ def bitcoin_client(): def test_make_squeak(bitcoin_client, lightning_client, signing_profile): squeak_core = SqueakCore(bitcoin_client, lightning_client) - squeak_entry = squeak_core.make_squeak(signing_profile, "hello") + squeak = squeak_core.make_squeak(signing_profile, "hello") - assert squeak_entry.squeak.GetDecryptedContentStr() == "hello" - - validated_squeak_entry = squeak_core.validate_squeak(squeak_entry.squeak) - - assert validated_squeak_entry == squeak_entry + assert squeak.GetDecryptedContentStr() == "hello" # def test_pay_offer(bitcoin_client, lightning_client, signing_profile):