def get_blockchain_from_db(self): """Fetch all blocks with their transactions from database Returns ------- List of all blocks """ self.open_connection(self.db_file) get_block = "SELECT * from {}".format(self.blockchain_table) get_transactions = "SELECT * FROM {} WHERE block_hash = ?".format(self.transaction_table) self.cursor.execute(get_block) blocks = [] blocks_db = self.cursor.fetchall() if len(blocks_db) == 0: return None for block_db in blocks_db: self.cursor.execute(get_transactions, (block_db[0],)) txns = [] txns_db = self.cursor.fetchall() if len(txns_db) != 0: for txn_db in txns_db: txn = Transaction(txn_db[0], txn_db[1], txn_db[2], txn_db[3]) txn.transaction_hash = txn_db[4] txns.append(txn) #txns=[] block = Block(block_id=block_db[1], merkle_tree_root=block_db[2], predecessor_hash=block_db[3], block_creator_id=block_db[4], transactions=txns, nonce=block_db[5], timestamp=float(block_db[6]), difficulty=int(block_db[7])) blocks.append(block) self.conn.close() return blocks
def test_set_signature(self): """Test for signature setting""" transaction = Transaction(sender="s", receiver="r", payload="1") self.assertTrue(isinstance(transaction, Transaction)) transaction.signature = "sig" self.assertEqual("r", transaction.receiver) self.assertEqual("sig", transaction.signature) self.assertEqual("1", transaction.payload) self.assertEqual("s", transaction.sender) try: transaction.signature = "sg" self.assertFalse(True) except ValueError: self.assertTrue(True)
def test_request_blocks_by_hash_range(self): """Test case #13.""" # given self.available_blocks[2] = Block( 2, 'test_merkle_hash', 'test_pred_block_hash', 'test_creator', [ Transaction('test_sender', 'test_receiver', 'test_payload', 'test_signature') ], nonce=5, timestamp=1337.0) # when json_rpc_request = { "jsonrpc": "2.0", "method": "requestBlocksByHashRange", "params": [], "id": 1 } response = self.make_request(json.dumps(json_rpc_request)) # then self.assert_json_equal( response, '{ "jsonrpc": "2.0", "result": [{"nr": 2, "timestamp": 1337.0, ' '"merkleHash" : "test_merkle_hash", ' '"difficulty" : -1,' '"predecessorBlock" : "test_pred_block_hash", "nonce" : 5, ' '"creator" : "test_creator", "transactions" : ' '[{"sender": "test_sender", "receiver": "test_receiver", ' '"payload": "test_payload", "signature": "test_signature"}]}], "id":1}' )
def test_from_dict(self): """Test transaction creation from dict""" d = {'sender': 's', 'receiver': 'r', 'payload': '1', 'signature': 'sig'} transaction = Transaction.from_dict(d) self.assertTrue(isinstance(transaction, Transaction)) self.assertEqual("r", transaction.receiver) self.assertEqual("sig", transaction.signature) self.assertEqual("1", transaction.payload) self.assertEqual("s", transaction.sender)
def test_from_json(self): """Test transaction creation from json""" json_string = '{"receiver": "r", "signature": "sig", "payload": "1", "sender": "s"}' transaction = Transaction.from_json(json_string) self.assertTrue(isinstance(transaction, Transaction)) self.assertEqual("r", transaction.receiver) self.assertEqual("sig", transaction.signature) self.assertEqual("1", transaction.payload) self.assertEqual("s", transaction.sender)
def from_dict(data_dict): """Instantiate a Block from a data dictionary.""" return Block(block_id=data_dict['nr'], merkle_tree_root=data_dict['merkleHash'], predecessor_hash=data_dict['predecessorBlock'], block_creator_id=data_dict['creator'], transactions=[ Transaction.from_dict(transaction_dict) for transaction_dict in data_dict['transactions'] ], nonce=data_dict['nonce'], timestamp=data_dict['timestamp'], difficulty=data_dict['difficulty'])
def requestTransaction(self, transaction_hash): """Returns the tuple (transaction, block hash of transaction).""" responses = self._bulk_send('requestTransaction', [transaction_hash], return_on_first_success=True) if responses: if responses[0]: transaction, block_hash = responses[0] return Transaction.from_dict(transaction), block_hash else: raise TransactionDoesNotExistException() else: raise NoPeersException( 'No nodes available to request the transaction from')
def from_dict(data_dict, consesnus_obj=None): """Instantiate a LogicalBlock from a data dictionary.""" _transactions = [] if data_dict['transactions']: _transactions = data_dict['transactions'] return LogicalBlock(block_id=data_dict['nr'], merkle_tree_root=data_dict['merkleHash'], predecessor_hash=data_dict['predecessorBlock'], block_creator_id=data_dict['creator'], transactions=[ Transaction.from_dict(transaction_dict) for transaction_dict in _transactions ], nonce=data_dict['nonce'], difficulty=data_dict['difficulty'], timestamp=data_dict['timestamp'], consensus_obj=consesnus_obj)
def __handle_send_transaction(self, transaction_data): transaction = Transaction.from_dict(transaction_data) transaction_hash = self.crypto_helper.hash(transaction.get_json()) transaction_in_pool, _ = self.get_transaction_callback( transaction_hash) self.on_transaction_received_callback(transaction) if not self.get_transaction_callback(transaction_hash)[0]: # if transaction still not present, it must have been delined self.__add_transaction_to_cache(transaction) if not transaction_in_pool == transaction and not self.__transaction_in_cache( transaction): logger.debug('Broadcasting transaction: {}'.format( str(transaction))) logger.debug('Broadcasting transaction hash: ' + str(transaction_hash)) try: self._call_threaded(self.sendTransaction, [transaction]) except NoPeersException: pass
def test_send_block_client_valid(self): """Test Case #8""" # Given self.add_peer('192.168.100.4', 6666) now = time.time() test_block = Block(2, 'merkle_hash123', 'pre_hash123', 'test_creator', [ Transaction('test_sender', 'test_receiver', 'test_payload', 'test_signature') ], 6969, now) # when self.json_rpc_client.queue_response({ 'jsonrpc': '2.0', 'result': None, 'id': 1 }) self.network_interface.sendBlock(test_block) # then last_request_method, last_request_params = self.get_last_request( '192.168.100.4', 6666) self.assertEqual(last_request_method, 'sendBlock') self.assert_json_equal(last_request_params, [{ 'nr': 2, 'timestamp': now, 'merkleHash': 'merkle_hash123', 'predecessorBlock': 'pre_hash123', 'nonce': 6969, 'creator': 'test_creator', 'difficulty': -1, 'transactions': [{ 'sender': 'test_sender', 'receiver': 'test_receiver', 'payload': 'test_payload', 'signature': 'test_signature' }] }])
def test_show_transaction_with_existing_transaction(self): """ Test case: #11 Tested requirement: #200 """ # given transaction = Transaction('some_sender_id', 'some_receiver_id', 'some_payload', 'some_signature') self.add_transaction(transaction) transaction_hash = self.mock_crypto_helper.hash_transaction( transaction) # when self.queue_input('4') self.queue_input(transaction_hash) self.queue_input('') self.queue_input('5') self.client.main() # then self.assert_string_in_output('some_sender_id') self.assert_string_in_output('some_receiver_id') self.assert_string_in_output('some_sender_id') self.assert_string_in_output('some_payload')
def test_request_transaction(self): """test case #9 """ # given self.add_peer('192.168.100.4', 6666) self.available_transactions['hash_of_transaction_#1'] = Transaction( "test_sender", "test_receiver", "test_payload", "test_signature") # when json_rpc_request = { "jsonrpc": "2.0", "method": "requestTransaction", "params": ["hash_of_transaction_#1"], "id": 1 } response = self.make_request(json.dumps(json_rpc_request)) # then self.assert_json_equal( response, '{"result": [{"sender": "test_sender", "receiver": "test_receiver", ' '"payload": "test_payload", "signature": "test_signature"}, "test_block_hash"], "id": 1,"jsonrpc": "2.0"}' )
def test_request_block_from_nonempty_blockchain(self): """ Test case: #10 Tested requirement: #210 """ # given transactions = [] for i in range(5): transactions.append( Transaction("test_sender", "test_receiver", "payload_data")) block0 = Block(0, "merkle_tree_hash_qthq4thi4q4t", 'pred_hash_1', "creator_hash", transactions, 123) block1 = Block( 1, "merkle_tree_hash_qthq5thi4q1t", 'pred_hash_2', "creator_hash", transactions, 456, ) self.add_block(block0) self.add_block(block1) # when self.queue_input('3') self.queue_input('1') self.queue_input('1') self.queue_input('') # press enter self.queue_input('3') self.queue_input('5') self.client.main() # then self.assert_string_in_output('1') # block number self.assert_string_in_output( 'merkle_tree_hash_qthq5thi4q1t') # merkle tree root self.assert_string_in_output('pred_hash_2') # predecessor hash self.assert_string_in_output('456') # nonce self.assert_string_in_output('creator_hash') # block creator
def create_transactions(self): pr_key1, pub_key1 = self.crypto_helper_obj.generate_key_pair() pr_key2, pub_key2 = self.crypto_helper_obj.generate_key_pair() pr_key3, pub_key3 = self.crypto_helper_obj.generate_key_pair() pr_key4, pub_key4 = self.crypto_helper_obj.generate_key_pair() self.txn1 = Transaction(pub_key1, pub_key2, "Payload1") self.txn2 = Transaction(pub_key2, pub_key4, "Payload2") self.txn3 = Transaction(pub_key3, pub_key1, "Payload3") self.txn4 = Transaction(pub_key4, pub_key3, "Payload3") self.txn1.sign_transaction(self.crypto_helper_obj, pr_key1) self.txn2.sign_transaction(self.crypto_helper_obj, pr_key2) self.txn3.sign_transaction(self.crypto_helper_obj, pr_key3) self.txn4.sign_transaction(self.crypto_helper_obj, pr_key4) self.txn1.transaction_hash = self.crypto_helper_obj.hash( self.txn1.get_json()) self.txn2.transaction_hash = self.crypto_helper_obj.hash( self.txn2.get_json()) self.txn3.transaction_hash = self.crypto_helper_obj.hash( self.txn3.get_json()) self.txn4.transaction_hash = self.crypto_helper_obj.hash( self.txn4.get_json())
def test_send_transaction_client_valid(self): """Test Case #6""" # given self.add_peer('192.168.2.3', 6666) test_transaction = Transaction('test_sender', 'test_receiver', 'test_payload', 'test_signature') # when self.json_rpc_client.queue_response({ 'jsonrpc': '2.0', 'result': True, 'id': 1 }) self.network_interface.sendTransaction(test_transaction) # then last_request_method, last_request_params = self.get_last_request( '192.168.2.3', 6666) self.assertEqual(last_request_method, 'sendTransaction') self.assertEqual(last_request_params, [{ "sender": "test_sender", "receiver": "test_receiver", "payload": "test_payload", "signature": "test_signature" }])
from labchain.datastructure.transaction import Transaction from tests.test_account import MockCryptoHelper from labchain.network.networking import ServerNetworkInterface, JsonRpcClient project_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir)) if project_dir not in sys.path: sys.path.append(project_dir) # change to DEBUG to see more output LOG_LEVEL = logging.INFO # change the polling interval POLL_INTERVAL = 10 BLOCK = Block(1, 'some_root', 'pred_hash', 'creator_id', [Transaction('some sender', 'some_receiver', 'some_payload', 'some_signature')], 1234) RECEIVED_BLOCKS = {} def get_block(block_id): if block_id in RECEIVED_BLOCKS: return [RECEIVED_BLOCKS[block_id]] return [] def on_block_received(received_block): RECEIVED_BLOCKS[received_block.block_id] = received_block logging.warning('Received block: {}'.format(received_block))
def show(self): """Start the wizard.""" clear_screen() # convert dict to an ordered list # this needs to be done to get an ordered list that does not change # at runtime of the function wallet_list = self.__wallet_to_list() # check if wallet contains any keys # case: wallet not empty if not len(self.wallet) == 0: chosen_key = self.__ask_for_key_from_wallet(wallet_list) if chosen_key == '': return # ask for valid sender input in a loop while not self.__validate_sender_input(chosen_key): chosen_key = self.__ask_for_key_from_wallet(wallet_list) if chosen_key == '': return clear_screen() print('Invalid input! Please choose a correct index!') print() clear_screen() print(u'Sender: ' + str(chosen_key)) chosen_receiver = self.__ask_for_receiver() while not self.__validate_receiver_input(chosen_receiver): # clear_screen() print('Invalid input! Please choose a correct receiver!') print(u'Sender: ' + str(chosen_key)) chosen_receiver = self.__ask_for_receiver() print() clear_screen() print(u'Sender: ' + str(chosen_key)) print(u'Receiver: ' + str(chosen_receiver)) chosen_payload = self.__ask_for_payload() while not self.__validate_payload_input(chosen_payload): # clear_screen() print('Invalid input! Please choose a correct payload!') print(u'Sender: ' + str(chosen_key)) print(u'Receiver: ' + str(chosen_receiver)) chosen_payload = self.__ask_for_payload() print() clear_screen() # Create transaction Object and send to network private_key = wallet_list[int(chosen_key) - 1][2] public_key = wallet_list[int(chosen_key) - 1][1] new_transaction = Transaction(str(public_key), str(chosen_receiver), str(chosen_payload)) new_transaction.sign_transaction(self.crypto_helper, private_key) transaction_hash = self.crypto_helper.hash(new_transaction.get_json()) self.network_interface.sendTransaction(new_transaction) print('Transaction successfully created!') print() print(u'Sender: ' + public_key) print(u'Receiver: ' + str(chosen_receiver)) print(u'Payload: ' + str(chosen_payload)) print(u'Hash: ' + str(transaction_hash)) print() # case: wallet is empty else: print(u'Wallet does not contain any keys! Please create one first!') input('Press any key to go back to the main menu!')
class DbTestCase(unittest.TestCase): def setUp(self): self.database = Db(block_chain_db_file=os.path.abspath( os.path.join(os.path.dirname(__file__), '../labchain/resources/labchaindb.sqlite'))) self.init_components() self.create_transactions() self.create_blocks() def test_create_tables(self): self.assertTrue(self.database.create_tables()) def test_save_block(self): self.assertTrue(self.database.save_block(self.block1)) self.database.get_blockchain_from_db() def init_components(self): node_config = './labchain/resources/node_configuration.ini' config_reader = ConfigReader(node_config) tolerance = config_reader.get_config(section='BLOCK_CHAIN', option='TOLERANCE_LEVEL') pruning = config_reader.get_config(section='BLOCK_CHAIN', option='TIME_TO_PRUNE') min_blocks = config_reader.get_config( section='MINING', option='NUM_OF_BLOCKS_FOR_DIFFICULTY') self.consensus = Consensus() self.crypto_helper_obj = crypto.instance() self.txpool = TxPool(self.crypto_helper_obj) self.block_list = [] self.blockchain = BlockChain(node_id="nodeId1", tolerance_value=tolerance, pruning_interval=pruning, consensus_obj=self.consensus, txpool_obj=self.txpool, crypto_helper_obj=self.crypto_helper_obj, min_blocks_for_difficulty=min_blocks, db=self.database, q=None) def create_transactions(self): pr_key1, pub_key1 = self.crypto_helper_obj.generate_key_pair() pr_key2, pub_key2 = self.crypto_helper_obj.generate_key_pair() pr_key3, pub_key3 = self.crypto_helper_obj.generate_key_pair() pr_key4, pub_key4 = self.crypto_helper_obj.generate_key_pair() self.txn1 = Transaction(pub_key1, pub_key2, "Payload1") self.txn2 = Transaction(pub_key2, pub_key4, "Payload2") self.txn3 = Transaction(pub_key3, pub_key1, "Payload3") self.txn4 = Transaction(pub_key4, pub_key3, "Payload3") self.txn1.sign_transaction(self.crypto_helper_obj, pr_key1) self.txn2.sign_transaction(self.crypto_helper_obj, pr_key2) self.txn3.sign_transaction(self.crypto_helper_obj, pr_key3) self.txn4.sign_transaction(self.crypto_helper_obj, pr_key4) self.txn1.transaction_hash = self.crypto_helper_obj.hash( self.txn1.get_json()) self.txn2.transaction_hash = self.crypto_helper_obj.hash( self.txn2.get_json()) self.txn3.transaction_hash = self.crypto_helper_obj.hash( self.txn3.get_json()) self.txn4.transaction_hash = self.crypto_helper_obj.hash( self.txn4.get_json()) def create_blocks(self): self.block1 = self.blockchain.create_block([self.txn1, self.txn2]) self.block2 = self.blockchain.create_block([self.txn3, self.txn4]) self.block3 = self.blockchain.create_block([self.txn1, self.txn4]) self.block4 = self.blockchain.create_block([self.txn1, self.txn3]) self.block5 = self.blockchain.create_block([self.txn1, self.txn2]) self.block6 = self.blockchain.create_block([self.txn3, self.txn4]) self.block7 = self.blockchain.create_block([self.txn2, self.txn4])
from labchain.network import networking from labchain.datastructure.transaction import Transaction from tests.test_account import MockCryptoHelper from labchain.network.networking import ServerNetworkInterface, JsonRpcClient project_dir = os.path.abspath( os.path.join(os.path.dirname(__file__), os.pardir, os.pardir)) if project_dir not in sys.path: sys.path.append(project_dir) # change to DEBUG to see more output LOG_LEVEL = logging.INFO # change the polling interval POLL_INTERVAL = 10 TRANSACTION = Transaction('some sender', 'some_receiver', 'some_payload', 'some_signature') RECEIVED_TRANSACTIONS = {} def get_transaction(transaction_hash): if transaction_hash in RECEIVED_TRANSACTIONS: return RECEIVED_TRANSACTIONS[transaction_hash], 'fake_block_hash' return None, None def on_transaction_received(received_transaction): transaction_hash = hashlib.sha256(received_transaction.get_json().encode()) RECEIVED_TRANSACTIONS[transaction_hash] = received_transaction logging.warning('Received transaction: {}'.format(received_transaction))
class BlockChainComponent(unittest.TestCase): """Class of testcases for the Blockchain module""" def setUp(self): """Setup phase for each testcase""" self.init_components() self.create_transactions() self.create_blocks() def test_get_block_range(self): # get_block_range doesn't consider genesis block so expected length = 0 blocks = self.blockchain.get_block_range(0) self.assertEqual(len(blocks), 0) def test_get_block_by_id(self): # fetching first block whose id = 0 blocks = self.blockchain.get_block_by_id(0) for block in blocks: self.assertEqual(block._block_id, 0) def test_get_block_by_hash(self): block_info = json.loads( self.blockchain.get_block_by_hash( self.blockchain._first_block_hash)) self.assertEqual(block_info['nr'], 0) def test_add_block(self): self.blockchain.add_block(self.block1) #blocks = self.blockchain.get_block_range(0) #self.assertEqual(len(blocks), 1) """ def test_add_block1(self): # now block8 has a branch with block 6 self.block8 = self.block1 = self.blockchain.create_block([self.txn2, self.txn4]) self.assertFalse(self.blockchain.add_block(self.block8), "Block is deleted") # block 9 has a normal predecessor block 7 self.block9 = self.block1 = self.blockchain.create_block([self.txn2, self.txn4]) self.assertTrue(self.blockchain.add_block(self.block9), "Block is saved") """ def test_switch_to_longest_branch(self): # now block8 has a branch with block 6 self.block8 = self.block1 = self.blockchain.create_block( [self.txn2, self.txn4]) # we are trying to add a new block in the block chain self.blockchain._blockchain[self.crypto_helper_obj.hash( self.block8.get_json())] = self.block8 # calculating the length of the blockchain before adding new block prev_block_length = len(self.blockchain._blockchain.items()) # calling the switching branch method self.blockchain.switch_to_longest_branch() # calculating the length of the blockchain after adding new block after_block_length = len(self.blockchain._blockchain.items()) # after branch switching the length of the block should be same self.assertEqual(prev_block_length, after_block_length, "Block is deleted") def test_calculate_diff(self): # blocks added in setup blocks, t1, t2, diff = self.blockchain.calculate_diff() self.assertIsNotNone(blocks) self.assertIsNotNone(t1) self.assertIsNotNone(t2) self.assertIsNotNone(diff) def test_create_block(self): # creating new block based on given transaction list new_block = self.blockchain.create_block([self.txn2, self.txn4]) self.assertIsNotNone(new_block, "New block Created") """ def test_send_block_to_neighbour(self): block_as_json = self.blockchain.send_block_to_neighbour(self.block1) block_as_object = Block.from_json(block_as_json) self.assertIsInstance(block_as_object, Block, "Sent the Block information requested by any neighbour") """ def request_block_from_neighbour(self): self.assertEqual(1, 2 - 1, "They are equal") def init_components(self): node_config = './labchain/resources/node_configuration.ini' config_reader = ConfigReader(node_config) tolerance = config_reader.get_config(section='BLOCK_CHAIN', option='TOLERANCE_LEVEL') pruning = config_reader.get_config(section='BLOCK_CHAIN', option='TIME_TO_PRUNE') min_blocks = config_reader.get_config( section='MINING', option='NUM_OF_BLOCKS_FOR_DIFFICULTY') self.consensus = Consensus() self.crypto_helper_obj = crypto.instance() self.txpool = TxPool(self.crypto_helper_obj) self.block_list = [] self.blockchain = BlockChain(node_id="nodeId1", tolerance_value=tolerance, pruning_interval=pruning, consensus_obj=self.consensus, txpool_obj=self.txpool, crypto_helper_obj=self.crypto_helper_obj, min_blocks_for_difficulty=min_blocks, db=None, q=None) def create_transactions(self): pr_key1, pub_key1 = self.crypto_helper_obj.generate_key_pair() pr_key2, pub_key2 = self.crypto_helper_obj.generate_key_pair() pr_key3, pub_key3 = self.crypto_helper_obj.generate_key_pair() pr_key4, pub_key4 = self.crypto_helper_obj.generate_key_pair() self.txn1 = Transaction(pub_key1, pub_key2, "Payload1") self.txn2 = Transaction(pub_key2, pub_key4, "Payload2") self.txn3 = Transaction(pub_key3, pub_key1, "Payload3") self.txn4 = Transaction(pub_key4, pub_key3, "Payload3") self.txn1.sign_transaction(self.crypto_helper_obj, pr_key1) self.txn2.sign_transaction(self.crypto_helper_obj, pr_key2) self.txn3.sign_transaction(self.crypto_helper_obj, pr_key3) self.txn4.sign_transaction(self.crypto_helper_obj, pr_key4) self.txn1.transaction_hash = self.crypto_helper_obj.hash( self.txn1.get_json()) self.txn2.transaction_hash = self.crypto_helper_obj.hash( self.txn2.get_json()) self.txn3.transaction_hash = self.crypto_helper_obj.hash( self.txn3.get_json()) self.txn4.transaction_hash = self.crypto_helper_obj.hash( self.txn4.get_json()) def create_blocks(self): self.block1 = self.blockchain.create_block([self.txn1, self.txn2]) self.block2 = self.blockchain.create_block([self.txn3, self.txn4]) self.block3 = self.blockchain.create_block([self.txn1, self.txn4]) self.block4 = self.blockchain.create_block([self.txn1, self.txn3]) self.block5 = self.blockchain.create_block([self.txn1, self.txn2]) self.block6 = self.blockchain.create_block([self.txn3, self.txn4]) self.block7 = self.blockchain.create_block([self.txn2, self.txn4])