def test_adding_invalid_new_block(self): storage = BlocksStorage(self.storage_filepath) storage.delete_all_blocks_from_mempool() bl = Block( "1549261064", "0000000000000000000000000000000000000000000000000000000000000000", [ "01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff080000000000000000ffffffff0100f2052a010000001976a914e8e4b375038b0a1a1dc70543eab7ea6ce279df4388ac00000000" ]) bl.nonce = 438 bl.hash_value = bl.get_hash() storage.add_block_to_storage(bl) new_block = Block( "1549263339", "00b6e2b6784a067bdb5f19a1f9347cc3c6277d3689fd2e164acd10e6e9eb5e86", [ "01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff080000000000000001ffffffff0100f2052a010000001976a914e8e4b375038b0a1a1dc70543eab7ea6ce279df4388ac00000000" ]) new_block.nonce = 44 new_block.hash_value = new_block.get_hash() bl_list = storage.get_all_blocks() self.assertEqual(1, len(bl_list)) storage.add_block_to_storage(new_block) bl_list = storage.get_all_blocks() self.assertEqual(1, len(bl_list)) self.assertFalse(str(new_block) in [str(b) for b in bl_list])
def test_difficulty_recalculation_works(self): storage = BlockchainMetaStorage(self.storage_filepath) storage.fill_storage_with_default_data() block_list = [ Block( "1549643265", "00905ae710fe1fed3d07192937c908e89988038baee05ecec28780ebcac88a83", [ "01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff080000000000000000ffffffff0100f2052a010000001976a914e8e4b375038b0a1a1dc70543eab7ea6ce279df4388ac00000000" ]), Block( "1549643285", "0003eb64ffaebce0832d0b097791b1c7e4c926cc505bf98308c2d8c8fd5c87b8", [ "01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff080000000000000000ffffffff0100f2052a010000001976a914e8e4b375038b0a1a1dc70543eab7ea6ce279df4388ac00000000" ]), Block( "1549643371", "0000f4de2a720701953a5b2dfb4e18fbdbadb2b3a15f17a36ea4823acb69ef9b", [ "01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff080000000000000000ffffffff0100f2052a010000001976a914e8e4b375038b0a1a1dc70543eab7ea6ce279df4388ac00000000" ]) ] old_meta = storage.get_meta() storage.recalculate_difficulty(block_list) meta = storage.get_meta() self.assertNotEqual(old_meta['current_target'], meta['current_target'])
def test_json_serialize_deserialize(self): bl = Block( "1549261064", "00b6e2b6784a067bdb5f19a1f9347cc3c6277d36e2fd2e164acd10e6e9eb5e86", [ "01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff080000000000000000ffffffff0100f2052a010000001976a914e8e4b375038b0a1a1dc70543eab7ea6ce279df4388ac00000000" ] ) json_string = str(bl) restored_block = Block.from_json(json.loads(json_string)) self.assertEqual(bl.hash_value, restored_block.hash_value) self.assertEqual(str(bl), str(restored_block))
def genesis_block(self): target = requests.get(self.api_url + '/meta').json()['current_target'] genesis = Block( str(int(time.time())), 64 * '0', [Serializer.serialize_transaction(self.construct_miners_rewarding_transaction())], target ) return self.mine(block=genesis)
def create_block_with_loaded_transactions(self): data = requests.get(self.api_url + '/block').json() prev = data['block'] request_data = requests.get(self.api_url + '/transaction/pendings' + '?amount=3').json() tx_list = [Serializer.serialize_transaction(Transaction.from_dict(item)) for item in request_data] tx_list.append(Serializer.serialize_transaction(self.construct_miners_rewarding_transaction())) target = requests.get(self.api_url + '/meta').json()['current_target'] block = Block(str(int(time.time())), prev['hash_value'], tx_list, target) return block
def test_get_chain_length(self): storage = BlocksStorage(self.storage_filepath) storage.delete_all_blocks_from_mempool() bl = Block( "1549261064", "0000000000000000000000000000000000000000000000000000000000000000", [ "01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff080000000000000000ffffffff0100f2052a010000001976a914e8e4b375038b0a1a1dc70543eab7ea6ce279df4388ac00000000" ]) bl.nonce = 438 bl.hash_value = bl.get_hash() bl_list = storage.get_all_blocks() self.assertEqual(0, len(bl_list)) storage.add_block_to_storage(bl) bl_list = storage.get_all_blocks() self.assertEqual(1, len(bl_list))
def add_block_to_storage(self, b: Block): blocks_list = self.get_all_blocks() if not b.validate_all_transactions(): return False if len(blocks_list) != 0: if blocks_list[-1].hash_value != b.previous_block_hash: return False blocks_list.append(b) with open(self.storage_filepath, 'wb+') as fp: pickle.dump(blocks_list, fp) return True
def create_block_with_loaded_transactions(self): prev = requests.get(self.api_url + '/chain/block').json() request_data = requests.get(self.api_url + '/transaction/pendings' + '?amount=1').json() tx_list = [Serializer.serialize_transaction(Transaction.from_dict(item)) for item in request_data] if len(tx_list) > 0: wtxid_list = [Deserializer.deserialize_transaction(tx).wtxid for tx in tx_list] wtx_merkle = codecs.decode(get_merkle_root(wtxid_list), 'ascii') else: wtx_merkle = "" tx_list.append(Serializer.serialize_transaction(self.construct_miners_rewarding_transaction(wtx_merkle))) block = Block(str(int(time.time())), prev['hash_value'], tx_list) return block
def resolve_conflicts(self): nodes_list = requests.get(self.api_url + '/node').json() current_len = requests.get(self.api_url + '/chain/length').json()['chain_length'] longest = {'len': current_len, 'source': ''} for node in nodes_list: node_chain_len = requests.get( node + '/chain/length').json()['chain_length'] if node_chain_len > longest['len']: block_list = requests.get(node + '/chain').json() block_obj_list = [Block.from_json(b) for b in block_list] if Blockchain.is_valid_chain(block_obj_list): longest['len'] = node_chain_len longest['source'] = node if longest['source'] == '': return "" requests.delete(self.api_url + '/chain') for block in block_list: requests.post(self.api_url + '/chain/block', json.dumps(block)) return longest
def genesis_block(self): genesis = Block( str(int(time.time())), 64 * '0', [Serializer.serialize_transaction(self.construct_miners_rewarding_transaction(""))] ) return self.mine(block=genesis)