From 7d530b25f4bbbb61bebe0072a7759e944b0cc2fe Mon Sep 17 00:00:00 2001 From: Jonathan Zernik Date: Fri, 17 Jul 2020 16:42:22 -0700 Subject: [PATCH] Successfully create and get signing squeak profile (#74) --- init.sql | 10 ++++ itests/test.py | 16 +++++++ squeakserver/admin/rpc/squeak_admin.proto | 48 +++++++++++++++++++ .../admin/squeak_admin_server_handler.py | 24 ++++++++++ .../admin/squeak_admin_server_servicer.py | 21 ++++++++ squeakserver/server/postgres_db.py | 43 +++++++++++++++++ squeakserver/server/squeak_profile.py | 4 ++ 7 files changed, 166 insertions(+) create mode 100644 squeakserver/server/squeak_profile.py diff --git a/init.sql b/init.sql index 3973f09f..c4831f8d 100644 --- a/init.sql +++ b/init.sql @@ -20,3 +20,13 @@ CREATE TABLE IF NOT EXISTS squeak ( CREATE INDEX IF NOT EXISTS idx_squeak_address ON squeak(address); + +CREATE TABLE IF NOT EXISTS profile ( + profile_id SERIAL PRIMARY KEY, + created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + profile_name VARCHAR(64) NOT NULL, + private_key bytea, + address VARCHAR(35) UNIQUE NOT NULL, -- Maximum length of a bitcoin address is 35. + sharing BOOLEAN NOT NULL, + following BOOLEAN NOT NULL +); diff --git a/itests/test.py b/itests/test.py index 74fcb931..3d065fbf 100644 --- a/itests/test.py +++ b/itests/test.py @@ -258,6 +258,22 @@ def run(): print("Get balance response balance: " + str(get_balance_response.balance)) # assert get_balance_response.balance > 0 + # Create a new signing profile + profile_name = 'bob' + create_signing_profile_response = admin_stub.CreateSigningProfile(squeak_admin_pb2.CreateSigningProfileRequest( + profile_name=profile_name, + )) + print("Get create signing profile response: " + str(create_signing_profile_response)) + profile_id = create_signing_profile_response.profile_id + # assert profile_id >= 0 + + # Get the new squeak profile + get_squeak_profile_response = admin_stub.GetSqueakProfile(squeak_admin_pb2.GetSqueakProfileRequest( + profile_id=profile_id, + )) + print("Get squeak profile response: " + str(get_squeak_profile_response)) + assert get_squeak_profile_response.squeak_profile.profile_name == profile_name + if __name__ == '__main__': logging.basicConfig() diff --git a/squeakserver/admin/rpc/squeak_admin.proto b/squeakserver/admin/rpc/squeak_admin.proto index 1b0e0de7..415c8ab4 100644 --- a/squeakserver/admin/rpc/squeak_admin.proto +++ b/squeakserver/admin/rpc/squeak_admin.proto @@ -14,6 +14,14 @@ service SqueakAdmin { */ rpc GetBalance (GetBalanceRequest) returns (GetBalanceReply) {} + /** sqkadmin: `createsigningprofile` + */ + rpc CreateSigningProfile (CreateSigningProfileRequest) returns (CreateSigningProfileReply) {} + + /** sqkadmin: `getsqueakprofile` + */ + rpc GetSqueakProfile (GetSqueakProfileRequest) returns (GetSqueakProfileReply) {} + } message GetBalanceRequest { @@ -23,3 +31,43 @@ message GetBalanceReply { /// The wallet balance int64 balance = 1; } + +message CreateSigningProfileRequest { + /// The name of the new signing profile + string profile_name = 1; +} + +message CreateSigningProfileReply { + /// The profile id + int32 profile_id = 1; +} + +message GetSqueakProfileRequest { + /// The profile id + int32 profile_id = 1; +} + +message GetSqueakProfileReply { + /// The squeak profile + SqueakProfile squeak_profile = 1; +} + +message SqueakProfile { + /// The profile id + int32 profile_id = 1; + + /// The profile name + string profile_name = 2; + + /// The private key + bytes private_key = 3; + + /// The address + string address = 4; + + /// Sharing + bool sharing = 5; + + /// Following + bool following = 6; +} diff --git a/squeakserver/admin/squeak_admin_server_handler.py b/squeakserver/admin/squeak_admin_server_handler.py index a3cdccfd..77b8bcc2 100644 --- a/squeakserver/admin/squeak_admin_server_handler.py +++ b/squeakserver/admin/squeak_admin_server_handler.py @@ -14,6 +14,8 @@ from squeakserver.server.util import generate_offer_preimage from squeakserver.server.util import bxor from squeakserver.server.util import get_hash +from squeakserver.server.squeak_profile import SqueakProfile + logger = logging.getLogger(__name__) @@ -35,3 +37,25 @@ class SqueakAdminServerHandler(object): wallet_balance = self.lightning_client.get_wallet_balance() logger.info("Wallet balance: {}".format(wallet_balance)) return wallet_balance.total_balance + + def handle_create_signing_profile(self, profile_name): + logger.info("Handle create signing profile with name: {}".format(profile_name)) + signing_key = CSigningKey.generate() + verifying_key = signing_key.get_verifying_key() + address = CSqueakAddress.from_verifying_key(verifying_key) + squeak_profile = SqueakProfile( + profile_id=None, + profile_name=profile_name, + private_key=bytes(signing_key), + address=str(address), + sharing=False, + following=False, + ) + profile_id = self.postgres_db.insert_profile(squeak_profile) + logger.info("New profile_id: {}".format(profile_id)) + return profile_id + + def handle_get_squeak_profile(self, profile_id): + logger.info("Handle get squeak profile with id: {}".format(profile_id)) + squeak_profile = self.postgres_db.get_profile(profile_id) + return squeak_profile diff --git a/squeakserver/admin/squeak_admin_server_servicer.py b/squeakserver/admin/squeak_admin_server_servicer.py index f5b1b910..2137ab30 100644 --- a/squeakserver/admin/squeak_admin_server_servicer.py +++ b/squeakserver/admin/squeak_admin_server_servicer.py @@ -27,6 +27,27 @@ class SqueakAdminServerServicer(squeak_admin_pb2_grpc.SqueakAdminServicer): balance=total_balance, ) + def CreateSigningProfile(self, request, context): + profile_name = request.profile_name + profile_id = self.handler.handle_create_signing_profile(profile_name) + return squeak_admin_pb2.CreateSigningProfileReply( + profile_id=profile_id, + ) + + def GetSqueakProfile(self, request, context): + profile_id = request.profile_id + squeak_profile = self.handler.handle_get_squeak_profile(profile_id) + return squeak_admin_pb2.GetSqueakProfileReply( + squeak_profile=squeak_admin_pb2.SqueakProfile( + profile_id=squeak_profile.profile_id, + profile_name=squeak_profile.profile_name, + private_key=squeak_profile.private_key, + address=squeak_profile.address, + sharing=squeak_profile.sharing, + following=squeak_profile.following, + ) + ) + def serve(self): server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) squeak_admin_pb2_grpc.add_SqueakAdminServicer_to_server( diff --git a/squeakserver/server/postgres_db.py b/squeakserver/server/postgres_db.py index 52967217..3ad30532 100644 --- a/squeakserver/server/postgres_db.py +++ b/squeakserver/server/postgres_db.py @@ -11,6 +11,8 @@ from squeak.core.script import CScript from squeakserver.server.util import get_hash +from squeakserver.server.squeak_profile import SqueakProfile + logger = logging.getLogger(__name__) @@ -130,3 +132,44 @@ class PostgresDb(): for row in rows ] return hashes + + def insert_profile(self, squeak_profile): + """ Insert a new squeak profile. """ + sql = """ + INSERT INTO profile(profile_name, private_key, address, sharing, following) + VALUES(%s, %s, %s, %s, %s) + RETURNING profile_id; + """ + with self.get_cursor() as curs: + # execute the INSERT statement + curs.execute(sql, ( + squeak_profile.profile_name, + squeak_profile.private_key, + squeak_profile.address, + squeak_profile.sharing, + squeak_profile.following, + )) + logger.info('Inserted new profile') + # get the new profile id back + row = curs.fetchone() + logger.info('New profile id: {}'.format(row[0])) + return row[0] + + def get_profile(self, profile_id): + """ Get a profile. """ + sql = """ + SELECT * FROM profile WHERE profile_id=%s""" + + with self.get_cursor() as curs: + curs.execute(sql, (profile_id,)) + row = curs.fetchone() + + squeak_profile = SqueakProfile( + profile_id=row[0], + profile_name=row[2], + private_key=bytes(row[3]), + address=row[4], + sharing=row[5], + following=row[6], + ) + return squeak_profile diff --git a/squeakserver/server/squeak_profile.py b/squeakserver/server/squeak_profile.py new file mode 100644 index 00000000..64bebecb --- /dev/null +++ b/squeakserver/server/squeak_profile.py @@ -0,0 +1,4 @@ +from collections import namedtuple + + +SqueakProfile = namedtuple('SqueakProfile', 'profile_id, profile_name, private_key, address, sharing, following')