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
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