def test_get_contracts_by_amount_range():
    cf = ContractFilter(ContractFilter.AMOUNT, 100, 1000)
    contracts = ContractService.get_contracts_by_filter([cf], True)
    assert len(contracts) == 1
    assert contracts[0].get_sendable() == c1.get_sendable()
    cf.maximum = 10000
    contracts = ContractService.get_contracts_by_filter([cf], True)
    assert len(contracts) == 2
def test_get_all_contracts_by_owner():
    contracts = ContractService.get_all_contracts_by_owner('tc_matt')
    assert len(contracts) == 2
    for contract in contracts:
        assert contract.owner == 'tc_matt'

    contracts = ContractService.get_all_contracts_by_owner('tc_denys')
    assert len(contracts) == 1
    for contract in contracts:
        assert contract.owner == 'tc_denys'

    contracts = ContractService.get_all_contracts_by_owner('bad_key')
    assert len(contracts) == 0
def test_get_contracts_by_multiple():
    cf1 = ContractFilter(ContractFilter.AMOUNT, 50, 1000) # c2, c5, c1
    contracts = ContractService.get_contracts_by_filter([cf1], True)
    assert len(contracts) == 3

    cf2 = ContractFilter(ContractFilter.RATE, 0.4, 0.5) # c1, c5
    contracts = ContractService.get_contracts_by_filter([cf1, cf2], True)
    assert len(contracts) == 2

    cf3 = ContractFilter(ContractFilter.DURATION, 15404, 15404) # c5
    contracts = ContractService.get_contracts_by_filter([cf1, cf2, cf3], True)
    assert len(contracts) == 1

    contracts = ContractService.get_contracts_by_filter([cf1, cf2, cf3], False) # None
    assert len(contracts) == 0
Example #4
0
 def validate_signed_contract(balances, signed_contract):
     contract = ContractService.get_contract_by_hash(
         signed_contract.parent_hash)
     if contract != None:
         if signed_contract.amount == contract.amount:
             if signed_contract.signed_timestamp <= contract.sign_end_timestamp:
                 if balances.get(signed_contract.from_addr,
                                 0) >= signed_contract.amount:
                     balances[signed_contract.from_addr] = balances[
                         signed_contract.from_addr] - signed_contract.amount
                     sc_balance = balances.get(signed_contract._hash,
                                               (0, 0))
                     balances[signed_contract._hash] = (
                         sc_balance[0] + signed_contract.amount,
                         sc_balance[1])
                     print('Valid Signed Contract: ' +
                           signed_contract._hash)
                     return True, balances
                 else:
                     print('insufficient funds')
             else:
                 print('contract timed out')
         else:
             print("amounts don't match")
     else:
         print('contract not found')
     print('Invalid Signed Contract: ' + signed_contract._hash)
     return False, balances
def test_get_contracts_by_duration_range():
    cf = ContractFilter(ContractFilter.DURATION, 1000, 13040)
    contracts = ContractService.get_contracts_by_filter([cf], True)
    assert len(contracts) == 3
def test_get_contracts_by_created_range():
    cf = ContractFilter(ContractFilter.CREATED, now, now + 3000)
    contracts = ContractService.get_contracts_by_filter([cf], True)
    assert len(contracts) == 4
def test_get_contracts_by_rate_range():
    cf = ContractFilter(ContractFilter.RATE, 0.5, 0.7)
    contracts = ContractService.get_contracts_by_filter([cf], True)
    assert len(contracts) == 2
def test_get_contract_by_hash():
    contract = ContractService.get_contract_by_hash(c1._hash)
    assert c1.get_sendable() == contract.get_sendable()
def setup():
    ContractService.store_contract(c1)
    ContractService.store_contract(c2)
    ContractService.store_contract(c3)
    ContractService.store_contract(c4)
    ContractService.store_contract(c5)
def start_as_regular(bootstrap_host, peer_timeout=0, recv_data_size=2048, \
        socket_timeout=1):
    print('\t\tStarting as a regular node')
    global a_node
    global miner_private
    a_node = node.Node()
    a_node.join_network(bootstrap_host, peer_timeout=peer_timeout, recv_data_size=recv_data_size, \
            socket_timeout=socket_timeout, read_callback=regular_node_callback, wallet_callback=wallet_callback, \
            start_bootstrap=True, start_gossiping=True)
    a_node.make_silent(True)
    # need to have a way to shut it down
    # right now when trying to exit this just hangs
    exchange_manager = ExchangeManager()
    while True:
        user_input = input('\t\t\tEnter a command: ')
        if user_input == 'quit' or user_input == 'q':
            try:
                global kill_threads
                global block_mine_thread
                kill_threads = True
                exchange_manager.stop()
                if block_mine_thread is not None:
                    block_mine_thread.cancel()
            except Exception as ex:
                print('Error during quick, {}'.format(str(ex)))
            break
        elif user_input == 'height':
            try:
                print('Blocks {}'.format(BlockService.get_max_height()))
                print('Mem Transactions {}'.format(
                    len(TransactionService.get_all_mempool_transactions())))
                print('Mem POS Transactions {}'.format(
                    len(
                        BaseObjectService.get_all_mempool_objects(
                            PosTransaction))))
                print('Mem Contract Transactions {}'.format(
                    len(
                        BaseObjectService.get_all_mempool_objects(
                            ContractTransaction))))
                print('Mem Contracts {}'.format(
                    len(BaseObjectService.get_all_mempool_objects(Contract))))
                print('Mem Signed Contracts {}'.format(
                    len(
                        BaseObjectService.get_all_mempool_objects(
                            SignedContract))))
            except Exception as ex:
                print('Error during height calculation, {}'.format(str(ex)))
        elif user_input == 'test':
            pass
        elif user_input == 'who':
            print('Current miner is {}'.format(miner_private))
        elif user_input == 'miner' or user_input == 'm':
            try:
                run_miner()
            except Exception as ex:
                print('Error during starting miner, {}'.format(str(ex)))
        elif user_input == 'priv' or user_input == 'p':
            try:
                secret = input('\t\t\tNew miner : ')
                if secret == 'denys' or secret == 'd':
                    private_key = denys_private_key
                elif secret == 'william' or secret == 'will' or secret == 'w':
                    private_key = william_private_key
                elif secret == 'matt' or secret == 'm':
                    private_key = matt_private_key
                elif secret == 'steven' or secret == 's':
                    private_key = steven_private_key
                elif secret == 'naween' or secret == 'n':
                    private_key = naween_private_key
                else:
                    private_key = secret
                miner_private = private_key
            except Exception as ex:
                print("Error during miner's private key change, {}".format(
                    str(ex)))

        elif user_input == 'balances' or user_input == 'b':
            try:
                balances = BlockService.get_all_balances()
                print(balances)
            except Exception as ex:
                print('Error during balance calculation, {}'.format(str(ex)))

        elif user_input == 'signed contract' or user_input == 'sc':
            try:
                contract_addr = input('\t\t\tContract Hash : ')
                a_contract = ContractService.get_contract_by_hash(
                    contract_addr)
                print('contract hash = ' + a_contract._hash)

                secret = input('\t\t\tSignee : ')
                a_signed_contract = SignedContract('', '', \
                        sc_from_addr='', signed_timestamp=time.time(), \
                        parent_hash='', parent_signature='', parent_owner='', \
                        amount=10, rate=0.2, is_mempool=1, duration=60, \
                        created_timestamp=time.time(), sign_end_timestamp=time.time() + 1000)
                #        created_timestamp=time.time(), sign_end_timestamp=time.time() + 1000)
                if secret == 'denys' or secret == 'd':
                    private_key = denys_private_key
                elif secret == 'william' or secret == 'will' or secret == 'w':
                    private_key = william_private_key
                elif secret == 'matt' or secret == 'm':
                    private_key = matt_private_key
                elif secret == 'steven' or secret == 's':
                    private_key = steven_private_key
                elif secret == 'naween' or secret == 'n':
                    private_key = naween_private_key
                else:
                    continue
            # a_contract.owner = EcdsaHashing.recover_public_key_str(steven_private_key)
            # a_contract.update_signature(steven_private_key)
            # a_contract.update_hash()

                a_signed_contract.from_addr = EcdsaHashing.recover_public_key_str(
                    private_key)
                a_signed_contract.parent_hash = a_contract._hash
                a_signed_contract.parent_signature = a_contract.signature
                a_signed_contract.parent_owner = a_contract.owner
                a_signed_contract.amount = a_contract.amount
                a_signed_contract.rate = a_contract.rate
                a_signed_contract.duration = a_contract.duration
                a_signed_contract.created_timestamp = a_contract.created_timestamp
                a_signed_contract.sign_end_timestamp = a_contract.sign_end_timestamp
                a_signed_contract.update_signature(private_key)
                a_signed_contract.update_hash()
                send_a_contract(a_signed_contract, action='contract_signed')
                contract_lock.acquire()
                SignedContractService.store_signed_contract(a_signed_contract)
                contract_lock.release()
                print('\nSigned Contract hash : {}'.format(
                    a_signed_contract._hash))
            except Exception as ex:
                print('Error during signed contract creation, {}'.format(
                    str(ex)))

        elif user_input == 'contract' or user_input == 'c':
            try:
                secret = input('\t\t\tOwner : ')
                a_contract = Contract('', '', owner='', amount=10, \
                        rate=0.2, is_mempool=1, duration=60, \
                        created_timestamp=time.time(), sign_end_timestamp=time.time() + 240000)
                if secret == 'denys' or secret == 'd':
                    private_key = denys_private_key
                elif secret == 'william' or secret == 'will' or secret == 'w':
                    private_key = william_private_key
                elif secret == 'matt' or secret == 'm':
                    private_key = matt_private_key
                elif secret == 'steven' or secret == 's':
                    private_key = steven_private_key
                elif secret == 'naween' or secret == 'n':
                    private_key = naween_private_key
                else:
                    continue
                a_contract.owner = EcdsaHashing.recover_public_key_str(
                    private_key)
                a_contract.update_signature(private_key)
                a_contract.update_hash()
                send_a_contract(a_contract)
                contract_lock.acquire()
                ContractService.store_contract(a_contract)
                contract_lock.release()
                print('\nContract hash : {}'.format(a_contract._hash))
            except Exception as ex:
                print('Error during contract creation, {}'.format(str(ex)))

        elif user_input == 'contract transaction' or user_input == 'ct':
            try:
                rs = redis_service.RedisService()
                signed_contract_hash = input('\t\t\tSigned Contract Hash : ')
                signed_contract = SignedContractService.get_signed_contract_by_hash(
                    signed_contract_hash)
                owner = input('\t\t\tOwner: ')

                to_symbol = input('\t\t\tTo TPS or BTC: ')
                from_symbol = input('\t\t\tFrom TPS or BTC: ')
                amount = input('\t\t\tAmount: ')

                if owner == 'denys' or owner == 'd':
                    private_key = denys_private_key
                elif owner == 'william' or owner == 'will' or owner == 'w':
                    private_key = william_private_key
                elif owner == 'matt' or owner == 'm':
                    private_key = matt_private_key
                elif owner == 'steven' or owner == 's':
                    private_key = steven_private_key
                elif owner == 'naween' or owner == 'n':
                    private_key = naween_private_key
                else:
                    continue
            # public_key = EcdsaHashing.recover_public_key_str(private_key)
            # a_contract_transaction = ContractTransaction('', '', public_key, \
            #         'sc_contract_addr', 'BTC', 'TPS', 10, 1, time.time())
            # a_contract_transaction.price = 6000
            # a_contract_transaction.update_signature(private_key)
            # a_contract_transaction.update_hash()
                r = rs._connect()
                time_price = r.zrange('price_stamps', -1, -1, withscores=True)
                price = float(time_price[0][0])
                a_contract_transaction = ContractTransaction(
                    '', '', signed_contract.parent_owner,
                    signed_contract._hash, to_symbol, from_symbol, amount,
                    price, 1)
                a_contract_transaction.update_signature(private_key)
                a_contract_transaction.update_hash()
                send_a_transaction(a_contract_transaction,
                                   action='transaction_contract')
                transaction_lock.acquire()

                rs.store_object(a_contract_transaction)
                transaction_lock.release()
                print('\nContract Transaction hash : {}'.format(
                    a_contract_transaction._hash))
            except Exception as ex:
                print('Error during contract transaction creation, {}'.format(
                    str(ex)))

        elif user_input == 'pos' or user_input == 'pos_transaction' or user_input == 'pt':
            try:
                secret = input('\t\t\tFrom : ')
                if secret == 'denys' or secret == 'd':
                    private_key = denys_private_key
                elif secret == 'william' or secret == 'will' or secret == 'w':
                    private_key = william_private_key
                elif secret == 'matt' or secret == 'm':
                    private_key = matt_private_key
                elif secret == 'steven' or secret == 's':
                    private_key = steven_private_key
                elif secret == 'naween' or secret == 'n':
                    private_key = naween_private_key
                else:
                    private_key = secret
                public_key = EcdsaHashing.recover_public_key_str(private_key)
                amount = input('\t\t\tAmount: ')
                pos_transaction = PosTransaction('', '', public_key, amount, 1)
                pos_transaction.update_signature(private_key)
                pos_transaction.update_hash()
                # send pos_transaction
                send_a_transaction(pos_transaction, action='transaction_pos')
                print('\nPOS Transaction hash : {}'.format(
                    pos_transaction._hash))

                transaction_lock.acquire()
                rs = redis_service.RedisService()
                rs.store_object(pos_transaction)
                transaction_lock.release()
            except Exception as ex:
                print('Error during pos transaction creation, {}'.format(
                    str(ex)))

        elif user_input == 'trans' or user_input == 'transaction' or user_input == 't':
            try:
                secret = input('\t\t\tFrom : ')
                if secret == 'denys' or secret == 'd':
                    private_key = denys_private_key
                elif secret == 'william' or secret == 'will' or secret == 'w':
                    private_key = william_private_key
                elif secret == 'matt' or secret == 'm':
                    private_key = matt_private_key
                elif secret == 'steven' or secret == 's':
                    private_key = steven_private_key
                elif secret == 'naween' or secret == 'n':
                    private_key = naween_private_key
                else:
                    private_key = secret
                public_key = EcdsaHashing.recover_public_key_str(private_key)
                to_addr = input('\t\t\tTo addr: ')
                if to_addr == 'denys' or to_addr == 'd':
                    to_addr = EcdsaHashing.recover_public_key_str(
                        denys_private_key)
                elif to_addr == 'william' or to_addr == 'w' or to_addr == 'will':
                    to_addr = EcdsaHashing.recover_public_key_str(
                        william_private_key)
                elif to_addr == 'matt' or to_addr == 'm':
                    to_addr = EcdsaHashing.recover_public_key_str(
                        matt_private_key)
                elif to_addr == 'steven' or to_addr == 's':
                    to_addr = EcdsaHashing.recover_public_key_str(
                        steven_private_key)
                elif to_addr == 'naween' or to_addr == 'n':
                    to_addr = EcdsaHashing.recover_public_key_str(
                        naween_private_key)
                else:
                    # to_addr is already a given public key, no need to calculate it
                    pass
                    #to_addr = EcdsaHashing.recover_public_key_str(to_addr)
                from_addr = public_key
                amount = input('\t\t\tAmount: ')
                new_transaction = Transaction('', '', to_addr, from_addr,
                                              amount, 1)
                new_transaction.update_signature(private_key)
                new_transaction.update_hash()
                send_a_transaction(new_transaction)
                transaction_lock.acquire()
                print('\nTransaction hash : {}'.format(new_transaction._hash))
                rs = redis_service.RedisService()
                rs.store_object(new_transaction)
                transaction_lock.release()
            except Exception as ex:
                print('Error during transaction creation, {}'.format(str(ex)))
    a_node.close()
def wallet_callback(wallet_sock):
    while True:
        data = a_node.connection_manager.server.recv_msg(
            client_socket=wallet_sock)
        json_dic = json.loads(data)
        new_msg = message.Message.from_dict(json_dic)
        print(new_msg.action)
        if new_msg.action == 'get_user_info':
            pending = []
            transaction = []
            user_trans_history, transaction_balance = TransactionService.get_transactions_by_public_key(
                new_msg.data, True)
            balances = BlockService.get_all_balances()
            user_balance = balances.get(new_msg.data, 0)
            for trans in user_trans_history:
                if (trans.is_mempool == 1):
                    pending.append(trans.get_sendable())
                else:
                    transaction.append(trans.get_sendable())
            string_user_info_json = build_return_json([
                ("pending", pending), ("transaction", transaction),
                ("amount", user_balance)
            ])
            #print(string_user_info_json)
            a_node.connection_manager.server.send_msg(
                data=string_user_info_json, client_socket=wallet_sock)
            a_node.connection_manager.server.send_msg(
                data="end", client_socket=wallet_sock)
        elif new_msg.action == 'send_tx':
            t = Transaction.from_dict(new_msg.data)
            trans_signable = t.get_signable()
            trans_signable_json = json.dumps(trans_signable,
                                             sort_keys=True,
                                             separators=(',', ':'))
            status = EcdsaHashing.verify_signature_hex(t.from_addr,
                                                       t.signature,
                                                       trans_signable_json)
            if status == True:
                rs = redis_service.RedisService()
                transaction_lock.acquire()
                rs.store_object(t)
                transaction_lock.release()
                send_a_transaction(t)
                a_node.connection_manager.server.send_msg(
                    data="Transaction Successful", client_socket=wallet_sock)
            else:
                a_node.connection_manager.server.send_msg(
                    data="Transaction Failed", client_socket=wallet_sock)
            a_node.connection_manager.server.send_msg(
                data="end", client_socket=wallet_sock)
        elif new_msg.action == 'send_ctx':
            ctx = ContractTransaction.from_dict(new_msg.data)
            trans_signable = ctx.get_signable()
            trans_signable_json = json.dumps(trans_signable,
                                             sort_keys=True,
                                             separators=(',', ':'))
            status = EcdsaHashing.verify_signature_hex(ctx.from_addr,
                                                       ctx.signature,
                                                       trans_signable_json)
            if status == True:
                rs = redis_service.RedisService()
                transaction_lock.acquire()
                rs.store_object(ctx)
                transaction_lock.release()
                send_a_transaction(ctx, action='transaction_contract')
                a_node.connection_manager.server.send_msg(
                    data="Contract Transaction Successful",
                    client_socket=wallet_sock)
                a_node.connection_manager.server.send_msg(
                    data="end", client_socket=wallet_sock)
            else:
                a_node.connection_manager.server.send_msg(
                    data="Contract Transaction Failed",
                    client_socket=wallet_sock)
        elif new_msg.action == "get_all_ip":
            node_obj_list = a_node.connection_manager.peer_list
            ip_list = [node.get_ip_address() for node in node_obj_list]
            json_ip_list_str_return = build_return_json([("ipaddress_list",
                                                          ip_list)])
            print(json_ip_list_str_return)
            a_node.connection_manager.server.send_msg(
                data=json_ip_list_str_return, client_socket=wallet_sock)
            a_node.connection_manager.server.send_msg(
                data="end", client_socket=wallet_sock)
        elif new_msg.action == "get_contracts":
            contracts_filter = get_contracts_list(new_msg.data)
            contracts = ContractService.get_contracts_by_filter(
                contracts_filter, False)
            new_contracts = [contract.get_sendable() for contract in contracts]
            json_str_return = build_return_json([("available_contracts",
                                                  new_contracts)])
            a_node.connection_manager.server.send_msg(
                data=json_str_return, client_socket=wallet_sock)
            a_node.connection_manager.server.send_msg(
                data="end", client_socket=wallet_sock)
        elif new_msg.action == "get_signed_contracts":
            signed_contracts_filter = get_contracts_list(new_msg.data,
                                                         contract_type=2)
            signed_contracts = SignedContractService.get_signed_contracts_by_filter(
                signed_contracts_filter, False)
            new_signed_contracts = [
                contract.get_sendable() for contract in signed_contracts
            ]
            json_str_return = build_return_json([("signed_contracts",
                                                  new_signed_contracts)])
            a_node.connection_manager.server.send_msg(
                data=json_str_return, client_socket=wallet_sock)
            a_node.connection_manager.server.send_msg(
                data="end", client_socket=wallet_sock)
        elif new_msg.action == "publish_contract":
            c = Contract.from_dict(new_msg.data)
            contract_signable_json = c.get_signable()
            contract_signable_json_str = json.dumps(contract_signable_json,
                                                    sort_keys=True,
                                                    separators=(',', ':'))
            status = EcdsaHashing.verify_signature_hex(
                c.owner, c.signature, contract_signable_json_str)
            if status == True:
                contract_lock.acquire()
                ContractService.store_contract(c)
                contract_lock.release()
                send_a_contract(c)
                a_node.connection_manager.server.send_msg(
                    data="Contract Successfully Created",
                    client_socket=wallet_sock)
                a_node.connection_manager.server.send_msg(
                    data="end", client_socket=wallet_sock)
            else:
                a_node.connection_manager.server.send_msg(
                    data="Contract Cannot be created",
                    client_socket=wallet_sock)
        elif new_msg.action == "subscribe_to_contract":
            sc = SignedContract.from_dict(new_msg.data)
            signed_contract_signable_json = sc.get_signable()
            signed_contract_signable_json_str = json.dumps(
                signed_contract_signable_json,
                sort_keys=True,
                separators=(',', ':'))
            status = EcdsaHashing.verify_signature_hex(
                sc.from_addr, sc.signature, signed_contract_signable_json_str)
            if status == True:
                contract_lock.acquire()
                SignedContractService.store_signed_contract(sc)
                contract_lock.release()
                send_a_contract(sc, action='contract_signed')
                a_node.connection_manager.server.send_msg(
                    data="Successfully Subscribed", client_socket=wallet_sock)
                a_node.connection_manager.server.send_msg(
                    data="end", client_socket=wallet_sock)
            else:
                a_node.connection_manager.server.send_msg(
                    data="Cannot Subscribed", client_socket=wallet_sock)
        #the a list of user inside your contracts
        elif new_msg.action == "get_all_user_partipation_contract":
            user_contracts_sub = SignedContractService.get_all_signed_contracts_by_owner(
                new_msg.data["userPartipication"])
            new_user_contracts_sub = [
                contract.get_sendable() for contract in user_contracts_sub
            ]
            json_str_return = build_return_json([("contract_subscription",
                                                  new_user_contracts_sub)])
            a_node.connection_manager.server.send_msg(
                data=json_str_return, client_socket=wallet_sock)
            a_node.connection_manager.server.send_msg(
                data="end", client_socket=wallet_sock)
            pass
        #The user contract that they created
        elif new_msg.action == "get_user_contracts":
            all_contract = ContractService.get_all_contracts_by_owner(
                new_msg.data["userPublicKey"])
            new_contracts = [
                contract.get_sendable() for contract in all_contract
            ]
            json_str_return = build_return_json([("contract_owned",
                                                  new_contracts)])
            a_node.connection_manager.server.send_msg(
                data=json_str_return, client_socket=wallet_sock)
            a_node.connection_manager.server.send_msg(
                data="end", client_socket=wallet_sock)
        elif new_msg.action == "get_bitcoin_price":
            rs = redis_service.RedisService()
            r = rs._connect()
            price_time = r.zrange('price_stamps', -1, -1, withscores=True)
            price = float(price_time[0][0])
            height = BlockService.get_max_height()
            json_str_return = build_return_json([("bitcoinPrice", str(price)),
                                                 ("height", str(height))])
            a_node.connection_manager.server.send_msg(
                data=json_str_return, client_socket=wallet_sock)
            a_node.connection_manager.server.send_msg(
                data="end", client_socket=wallet_sock)
        elif new_msg.action == "get_contract_subscription":
            scs = SignedContractService.get_all_signed_contracts_by_from_addr(
                new_msg.data["userPublicKey"])
            new_contracts = [contract.get_sendable() for contract in scs]
            json_str_return = build_return_json([("user_contract_subscription",
                                                  new_contracts)])
            a_node.connection_manager.server.send_msg(
                data=json_str_return, client_socket=wallet_sock)
            a_node.connection_manager.server.send_msg(
                data="end", client_socket=wallet_sock)
        elif new_msg.action == "get_contracts_and_signed_contract_info":
            balances = BlockService.get_all_balances()
            #all contract owned
            all_contract = ContractService.get_all_contracts_by_owner(
                new_msg.data["userPublicKey"])
            all_contracts_str = [
                contract.get_sendable() for contract in all_contract
            ]
            #signed contract
            signed_contracts_sub = SignedContractService.get_all_signed_contracts_by_owner(
                new_msg.data["userPublicKey"])
            signed_contracts_sub_str = [
                contract.get_sendable() for contract in signed_contracts_sub
            ]
            # balances
            new_dict = {}
            for signed_contract in signed_contracts_sub:
                b = balances.get(signed_contract._hash, (0, 0))
                new_dict[signed_contract._hash] = b
            #history
            contract_transaction_history = ContractTransactionService.get_contract_transactions_from_public_key(
                new_msg.data["userPublicKey"], False)
            contract_transaction_history_str = [
                contract.get_sendable()
                for contract in contract_transaction_history
            ]
            json_str_return = build_return_json([
                ("contract_owned", all_contracts_str),
                ("contract_subscription", signed_contracts_sub_str),
                ("transaction_history", contract_transaction_history_str),
                ('balances', new_dict)
            ])
            a_node.connection_manager.server.send_msg(
                data=json_str_return, client_socket=wallet_sock)
            a_node.connection_manager.server.send_msg(
                data="end", client_socket=wallet_sock)
        elif new_msg.action == "get_signed_by_contract_hash":
            # signed contracts
            signed_contracts = SignedContractService.get_all_signed_contracts_by_contract_hash(
                new_msg.data['_hash'])
            signed_contracts_str = [
                sc.get_sendable() for sc in signed_contracts
            ]
            # contract
            contract = ContractService.get_contract_by_hash(
                new_msg.data['_hash'])
            contract_str = contract.get_sendable()

            json_str = build_return_json([('contract', contract_str),
                                          ('signed_contracts',
                                           signed_contracts_str)])
            a_node.connection_manager.server.send_msg(
                data=json_str, client_socket=wallet_sock)
            a_node.connection_manager.server.send_msg(
                data="end", client_socket=wallet_sock)
        elif new_msg.action == 'exit':
            break
        else:
            a_node.connection_manager.server.send_msg(
                data="Bad Data", client_socket=wallet_sock)
    a_node.connection_manager.server.close_client(client_socket=wallet_sock)
    def store_block(self, block):
        """
        Store an entire block in redis. Will store fields and lists of objects. Will not store anything if the block's hash already exists in the database.

        Arguments:
        block   -- Block object to be stored

        Returns:
        list    -- list containing results of each query used to store an object (0s and 1s)
                0s indicate that the field was updated (already present)
                1s indicate that the field is new and was stored
        """
        r = self._connect()

        #rs = RedisService()

        # key to store list of objects under
        name = self.key_suffix + block._hash
        # if block isn't in the database already
        if not r.exists(name):
            pipe = r.pipeline()
            # store timestamp first
            pipe.rpush(name, block.prev_block)
            pipe.rpush(name, block.height)
            pipe.rpush(name, block.owner)
            pipe.rpush(name, block.signature)
            pipe.rpush(name, block.timestamp)

            # store string 'transactions' to help with retrieval parsing
            pipe.rpush(name, 'transactions')
            for transaction in block.transactions:
                transaction.is_mempool = 0
                # check if transaction is in the mempool
                set_name = transaction._to_index()[-1] + ":is_mempool:1"
                t_key = transaction._to_index()[-1] + ":" + transaction._hash
                if r.sismember(set_name, t_key):
                    # remove from list of mempool objects
                    pipe.srem(set_name, t_key)

                # store the transaction's hash under the block's list
                pipe.rpush(name, transaction._hash)
                # store the actual transaction object

                pipe = self.rs.store_object(transaction, r, pipe)

            pipe.rpush(name, 'pos_transactions')
            for pos_transaction in block.pos_transactions:
                pos_transaction.is_mempool = 0
                # check if pos transaction is in the mempool
                set_name = pos_transaction._to_index()[-1] + ":is_mempool:1"
                pt_key = pos_transaction._to_index()[-1] + ":" + pos_transaction._hash
                if r.sismember(set_name, pt_key):
                    # remove from list of mempool objects
                    pipe.srem(set_name, pt_key)

                pipe.rpush(name, pos_transaction._hash)
                pipe = self.rs.store_object(pos_transaction, r, pipe)

            pipe.rpush(name, 'contract_transactions')
            for contract_transaction in block.contract_transactions:
                contract_transaction.is_mempool = 0
                # check if contract transaction is in the mempool
                set_name = contract_transaction._to_index()[-1] + ":is_mempool:1"
                ct_key = contract_transaction._to_index()[-1] + ":" + contract_transaction._hash
                if r.sismember(set_name, ct_key):
                    # remove from list of mempool objects
                    pipe.srem(set_name, ct_key)

                pipe.rpush(name, contract_transaction._hash)
                pipe = self.rs.store_object(contract_transaction, r, pipe)

            pipe.rpush(name, 'contracts')
            for contract in block.contracts:
                contract.is_mempool = 0
                # check if contract is in the mempool
                set_name = contract._to_index()[-1] + ":is_mempool:1"
                c_key = contract._to_index()[-1] + ":" + contract._hash
                if r.sismember(set_name, c_key):
                    # remove from list of mempool objects
                    pipe.srem(set_name, c_key)

                pipe.rpush(name, contract._hash)
                pipe = ContractService.store_contract(contract, pipe)

            pipe.rpush(name, 'signed_contracts')
            for signed_contract in block.signed_contracts:
                signed_contract.is_mempool = 0
                # check if signed contract is in the mempool
                set_name = signed_contract._to_index()[-1] + ":is_mempool:1"
                sc_key = signed_contract._to_index()[-1] + ":" + signed_contract._hash
                if r.sismember(set_name, sc_key):
                    # remove from list of mempool objects
                    pipe.srem(set_name, sc_key)

                pipe.rpush(name, signed_contract._hash)
                pipe = SignedContractService.store_signed_contract(signed_contract, pipe)

            pipe.rpush(name, 'terminated_contracts')
            for terminated_contract in block.terminated_contracts:
                pipe.rpush(name, terminated_contract._hash)
                pipe = self.rs.store_object(terminated_contract, r, pipe)

            pipe.zadd('blocks', block.height, block._hash)

            # TODO max block height will not always be this, will change
            pipe.set(self.max_block_height, block.height)

            pipe.sadd("block:" + str(block.height), block._hash)
            return pipe.execute()
        else:
            print("Block with hash: " + block._hash + " already exists. Unable to update.")
            return []
    def find_by_hash(self, block_hash):
        """
        Find a block using it's hash. Will return the block object, fully populated with all of the objects encased in it.

        Arguments:
        block_hash      -- hash of the block to retrieve

        Returns:
        block object    -- Block object containing all of the objects included in the block
        """
        r = self._connect()

        #rs = RedisService()

        # get key to retrieve list of block's fields
        name = self.key_suffix + block_hash

        if r.exists(name):
            # get all of the fields in the list
            hashes = r.lrange(name, 0, -1)

            # timestamp will always be first
            prev_block = hashes[0]
            # remove for iteration
            hashes.remove(prev_block)

            # timestamp will always be first
            height = hashes[0]
            # remove for iteration
            hashes.remove(height)

            # timestamp will always be first
            owner = hashes[0]
            # remove for iteration
            hashes.remove(owner)

            # timestamp will always be first
            signature = hashes[0]
            # remove for iteration
            hashes.remove(signature)

            # timestamp will always be first
            timestamp = hashes[0]
            # remove for iteration
            hashes.remove(timestamp)

            prefix = ''
            # list to hold all of the objects
            transactions = []
            pos_transactions = []
            contract_transactions = []
            contracts = []
            signed_contracts = []
            terminated_contracts = []

            # temporary list to copy from
            temp_list = []
            obj = None
            contract_section = False
            signed_contract_section = False
            terminated_contract_section = False
            for h in hashes:
                # if at a new type of object, change some variables
                if h == 'transactions':
                    prefix = Transaction._to_index()[-1]
                    obj = Transaction
                    continue
                elif h == 'pos_transactions':
                    prefix = PosTransaction._to_index()[-1]
                    obj = PosTransaction
                    transactions = temp_list.copy()
                    temp_list.clear()
                    continue
                elif h == 'contract_transactions':
                    prefix = ContractTransaction._to_index()[-1]
                    obj = ContractTransaction
                    pos_transactions = temp_list.copy()
                    temp_list.clear()
                    continue
                elif h == 'contracts':
                    contract_section = True
                elif h == 'signed_contracts':
                    contract_section = False
                    signed_contract_section = True
                elif h == 'terminated_contracts':
                    signed_contract_section = False
                    terminated_contract_section = True


                # get the object from redis and add to the temporary list
                if contract_section:
                    contract = ContractService.get_contract_by_hash(h)
                    if contract != None:
                        contracts.append(contract)
                elif signed_contract_section:
                    signed_contract = SignedContractService.get_signed_contract_by_hash(h)
                    if signed_contract != None:
                        signed_contracts.append(signed_contract)
                elif terminated_contract_section:
                    terminated_contract = self.rs.get_object_by_full_key('terminated_contract:' + h, TerminatedContract, r)
                    if terminated_contract != None:
                        terminated_contracts.append(terminated_contract)
                else:
                    t = self.rs.get_object_by_full_key(prefix + ":" + h, obj, r)
                    temp_list.append(t)

            contract_transactions = temp_list.copy()
            temp_list.clear()

            # create block object and return it
            block = Block(block_hash, signature, owner, prev_block, height, transactions, pos_transactions, contract_transactions, contracts, signed_contracts, terminated_contracts, timestamp)
            return block
        else:
            return None