def test_is_valid_block_jumped_difficulty(last_block, block): jumped_difficulty = 10 block.difficulty = jumped_difficulty block.hash = f'{"0" * jumped_difficulty}111abc' with pytest.raises(Exception, match='The block difficulty must only adjust by 1'): Block.is_valid_block(last_block, block)
def test_mined_block_difficulty_limits_at_1(): last_block = Block(time.time_ns(), 'test_last_hash', 'test_hash', 'test_data', 1, 0) time.sleep(MINE_RATE / SECONDS) mined_block = Block.mine_block(last_block, 'bar') assert mined_block.difficulty == 1
def test_slowly_mined_block(): last_block = Block.mine_block(Block.genesis(), 'foo') time.sleep( MINE_RATE / SECONDS ) # Delay to ensure it is mined slower than mine_rate, takes argument in second mined_block = Block.mine_block(last_block, 'bar') assert mined_block.difficulty == last_block.difficulty - 1
def test_mine_block(): last_block = Block.genesis() data = 'test-data' block = Block.mine_block(last_block, data) assert isinstance( block, Block ) # Check if the block we created became an instance or object of Block class assert block.data == data assert block.last_hash == last_block.hash assert hex_to_binary( block.hash)[0:block.difficulty] == '0' * block.difficulty
def is_valid_chain(chain): ''' Validate the blockchain using following rules - chain must start with genesis block - blocks must be formatted correctly ''' if chain[0].__dict__ != Block.genesis( ).__dict__: # Python can't check equality of two objects, but dictionaries raise Exception('The genesis block must be valid') for i in range(1, len(chain)): block = chain[i] last_block = chain[i - 1] Block.is_valid_block(last_block, block)
def test_genesis(): genesis = Block.genesis() assert isinstance(genesis, Block) for key, value in GENESIS_DATA.items(): getattr( genesis, key ) == value # Checks if all values of genesis object are same as that in original dictionary
def from_json(chain_json): ''' Deserialize a list of serialised blocks into Blockchain object or a chain of Block instances ''' blockchain = Blockchain() blockchain.chain = list( map(lambda block_json: Block.from_json(block_json), chain_json)) return blockchain
def message(self, pubnub, message_object): print( f'\n-- Channel: {message_object.channel} | Message: {message_object.message}' ) if message_object.channel == CHANNELS['BLOCK']: block = Block.from_json(message_object.message) potential_chain = self.blockchain.chain[:] potential_chain.append(block) try: self.blockchain.replace_chain(potential_chain) print('\n --Successfully replaced the local chain') except Exception as e: print(f'\n --Did not replace chain: {e}') elif message_object.channel == CHANNELS['TRANSACTION']: transaction = Transaction.from_json(message_object.message) self.transaction_pool.set_transaction(transaction) print('\n -- Set the new transaction in the transaction pool.')
def test_is_valid_block_bad_block_hash(last_block, block): block.hash = '000000000000000111abc' with pytest.raises(Exception, match='The block hash must be correct'): Block.is_valid_block(last_block, block)
def add_block(self, data): self.chain.append(Block.mine_block(self.chain[-1], data))
def test_is_valid_block_bad_proof_of_work(last_block, block): block.hash = 'fff' with pytest.raises(Exception, match='The proof of work requirement not met'): Block.is_valid_block(last_block, block)
def test_is_valid_block_bad_last_hash(last_block, block): block.last_hash = 'evil_last_hash' with pytest.raises( Exception, match='The block last hash must be correct' ): # Tells python that we are expecting this part of code to raise an exception with given exception message Block.is_valid_block(last_block, block)
def test_is_valid_block(last_block, block): Block.is_valid_block(last_block, block)
def block(last_block): return Block.mine_block(last_block, 'test_data')
def last_block(): return Block.genesis()
def __init__(self): self.chain = [Block.genesis()]
def test_quickly_mined_block(): last_block = Block.mine_block(Block.genesis(), 'foo') mined_block = Block.mine_block(last_block, 'bar') assert mined_block.difficulty == last_block.difficulty + 1