From 888eeeca6b429cc46c7c48fa7744a448bd1bc75b Mon Sep 17 00:00:00 2001 From: Jonathan Zernik Date: Sun, 19 Jul 2020 01:25:34 -0700 Subject: [PATCH] Return squeak with profile (#89) * Return squeakentry with profile using join in admin rpc. * Return squeak display entry successfully in itest. --- itests/test.py | 9 ++++ proto/squeak_admin.proto | 43 +++++++++++++++++ .../admin/squeak_admin_server_handler.py | 8 ++++ .../admin/squeak_admin_server_servicer.py | 13 +++++ squeakserver/core/squeak_entry.py | 2 +- .../core/squeak_entry_with_profile.py | 4 ++ squeakserver/node/squeak_node.py | 3 ++ squeakserver/server/postgres_db.py | 47 +++++++++++++++++++ 8 files changed, 128 insertions(+), 1 deletion(-) create mode 100644 squeakserver/core/squeak_entry_with_profile.py diff --git a/itests/test.py b/itests/test.py index 72957321..727ff6c6 100644 --- a/itests/test.py +++ b/itests/test.py @@ -303,6 +303,15 @@ def run(): print("Get balance response: " + str(get_balance_response)) assert get_balance_response.wallet_balance_response.total_balance == 1000 + # Get a squeak display item + get_squeak_display_response = admin_stub.GetSqueakDisplay( + squeak_admin_pb2.GetSqueakDisplayRequest( + hash=make_squeak_hash, + ) + ) + print("Get squeak display response: " + str(get_squeak_display_response)) + assert get_squeak_display_response.squeak_display_entry.content_str == "Hello from the profile on the server!" + if __name__ == "__main__": logging.basicConfig() diff --git a/proto/squeak_admin.proto b/proto/squeak_admin.proto index 4d8c73a6..9506aeb6 100644 --- a/proto/squeak_admin.proto +++ b/proto/squeak_admin.proto @@ -28,6 +28,10 @@ service SqueakAdmin { */ rpc MakeSqueak (MakeSqueakRequest) returns (MakeSqueakReply) {} + /** sqkadmin: `getsqueakdisplay` + */ + rpc GetSqueakDisplay (GetSqueakDisplayRequest) returns (GetSqueakDisplayReply) {} + } message GetBalanceRequest { @@ -93,3 +97,42 @@ message MakeSqueakReply { /// Hash of the created squeak. bytes hash = 1; } + +message GetSqueakDisplayRequest { + /// Hash of the squeak. + bytes hash = 1; +} + +message GetSqueakDisplayReply { + /// The squeak display entry + SqueakDisplayEntry squeak_display_entry = 1; +} + +message SqueakDisplayEntry { + /// The squeak hash. + string squeak_hash = 1; + + /// Is unlocked + bool is_unlocked = 2; + + /// The decrypted content + string content_str = 3; + + /// Is reply + bool is_reply = 4; + + /// Reply to hash + string reply_to = 5; + + /// Block height + int32 block_height = 6; + + /// Block time + int64 block_time = 7; + + /// Is author address known + bool is_author_known = 8; + + /// The author name + string author_name = 9; +} diff --git a/squeakserver/admin/squeak_admin_server_handler.py b/squeakserver/admin/squeak_admin_server_handler.py index 2051afaf..d62fbc8c 100644 --- a/squeakserver/admin/squeak_admin_server_handler.py +++ b/squeakserver/admin/squeak_admin_server_handler.py @@ -38,3 +38,11 @@ class SqueakAdminServerHandler(object): profile_id, content_str, replyto_hash ) return inserted_squeak_hash + + def handle_get_squeak_display_entry(self, squeak_hash): + logger.info("Handle get squeak display entry for hash: {}".format(squeak_hash)) + squeak_entry_with_profile = self.squeak_node.get_squeak_entry_with_profile( + squeak_hash + ) + logger.info("Got squeak entry with profile for hash: {}".format(squeak_entry_with_profile)) + return squeak_entry_with_profile diff --git a/squeakserver/admin/squeak_admin_server_servicer.py b/squeakserver/admin/squeak_admin_server_servicer.py index 59a7941e..2adbb07d 100644 --- a/squeakserver/admin/squeak_admin_server_servicer.py +++ b/squeakserver/admin/squeak_admin_server_servicer.py @@ -50,6 +50,19 @@ class SqueakAdminServerServicer(squeak_admin_pb2_grpc.SqueakAdminServicer): ) return squeak_admin_pb2.MakeSqueakReply(hash=squeak_hash,) + def GetSqueakDisplay(self, request, context): + squeak_hash = request.hash + squeak_entry_with_profile = self.handler.handle_get_squeak_display_entry(squeak_hash) + squeak_entry = squeak_entry_with_profile.squeak_entry + squeak = squeak_entry.squeak + return squeak_admin_pb2.GetSqueakDisplayReply( + squeak_display_entry=squeak_admin_pb2.SqueakDisplayEntry( + squeak_hash=squeak_hash.hex(), + is_unlocked=True, + content_str=squeak.GetDecryptedContentStr(), + ) + ) + def serve(self): server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) squeak_admin_pb2_grpc.add_SqueakAdminServicer_to_server(self, server) diff --git a/squeakserver/core/squeak_entry.py b/squeakserver/core/squeak_entry.py index 16f1847a..984b1af9 100644 --- a/squeakserver/core/squeak_entry.py +++ b/squeakserver/core/squeak_entry.py @@ -1,4 +1,4 @@ from collections import namedtuple -SqueakEntry = namedtuple("LightningAddress", ["squeak", "block_header"]) +SqueakEntry = namedtuple("SqueakEntry", ["squeak", "block_header"]) diff --git a/squeakserver/core/squeak_entry_with_profile.py b/squeakserver/core/squeak_entry_with_profile.py new file mode 100644 index 00000000..5d4865ca --- /dev/null +++ b/squeakserver/core/squeak_entry_with_profile.py @@ -0,0 +1,4 @@ +from collections import namedtuple + + +SqueakEntryWithProfile = namedtuple("SqueakEntryWithProfile", ["squeak_entry", "squeak_profile"]) diff --git a/squeakserver/node/squeak_node.py b/squeakserver/node/squeak_node.py index b7778d05..b5795aaa 100644 --- a/squeakserver/node/squeak_node.py +++ b/squeakserver/node/squeak_node.py @@ -119,3 +119,6 @@ class SqueakNode: squeak_maker = SqueakMaker(self.lightning_client) squeak = squeak_maker.make_squeak(squeak_profile, content_str, replyto_hash) return self.save_squeak(squeak) + + def get_squeak_entry_with_profile(self, squeak_hash): + return self.postgres_db.get_squeak_entry_with_profile(squeak_hash) diff --git a/squeakserver/server/postgres_db.py b/squeakserver/server/postgres_db.py index 5cb0f5cf..cab7cebd 100644 --- a/squeakserver/server/postgres_db.py +++ b/squeakserver/server/postgres_db.py @@ -7,6 +7,7 @@ from squeak.core import CSqueak from squeakserver.server.squeak_profile import SqueakProfile from squeakserver.server.util import get_hash from squeakserver.core.squeak_entry import SqueakEntry +from squeakserver.core.squeak_entry_with_profile import SqueakEntryWithProfile logger = logging.getLogger(__name__) @@ -108,6 +109,52 @@ class PostgresDb: block_header = row[17] return SqueakEntry(squeak=squeak, block_header=block_header) + def get_squeak_entry_with_profile(self, squeak_hash): + """ Get a squeak. """ + sql = """ + SELECT * FROM squeak + LEFT JOIN profile + ON squeak.address=profile.address + WHERE squeak.hash=%s + """ + + squeak_hash_str = squeak_hash.hex() + + with self.get_cursor() as curs: + curs.execute(sql, (squeak_hash_str,)) + row = curs.fetchone() + + squeak = CSqueak( + nVersion=row[2], + hashEncContent=bytes.fromhex(row[3]), + hashReplySqk=bytes.fromhex(row[4]), + hashBlock=bytes.fromhex(row[5]), + nBlockHeight=row[6], + vchScriptPubKey=bytes(row[7]), + vchEncryptionKey=bytes(row[8]), + encDatakey=bytes.fromhex(row[9]), + iv=bytes.fromhex((row[10])), + nTime=row[11], + nNonce=row[12], + encContent=bytes.fromhex((row[13])), + vchScriptSig=bytes(row[14]), + vchDecryptionKey=bytes(row[16]), + ) + block_header = row[17] + squeak_entry = SqueakEntry(squeak=squeak, block_header=block_header) + squeak_profile = SqueakProfile( + profile_id=row[18], + profile_name=row[20], + private_key=bytes(row[21]), + address=row[22], + sharing=row[23], + following=row[24], + ) + return SqueakEntryWithProfile( + squeak_entry=squeak_entry, + squeak_profile=squeak_profile, + ) + def lookup_squeaks(self, addresses, min_block, max_block): """ Lookup squeaks. """ sql = """