def test_is_valid_block_jumped_difficulty(last_block, block): jumped_difficulty = 10 block.difficulty = jumped_difficulty block.hash = f"{'0' * jumped_difficulty}111" with pytest.raises(Exception, match='Difficulty must adjust by one'): Block.is_valid_block(last_block, block)
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_is_valid_block_skipped_difficulty(last_block, block): block.difficulty = 10 block.hash = f'{"0"*block.difficulty}abcd' with pytest.raises(Exception, match="The block difficulty must only adjust by 1!"): Block.is_valid_block(last_block, block)
def test_is_valid_block_bad_last_hash(last_block, block): # Edit the last_hash data to manually trigger bad data block.last_hash = "evil_last_hash" # Expecting an exception to be thrown with exact match for exception message with pytest.raises(Exception, match="last_hash must be correct"): Block.is_valid_block(last_block, block)
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='difficulty must only adjust by 1'): Block.is_valid_block(last_block, block)
def test_is_valid_bad_block(): last_block = Block.genesis() block = Block.mine_block(last_block, 'foo') block.last_hash = 'evil_lash_harsh' with pytest.raises(Exception, match='he block last_hash must be correct'): Block.is_valid_block(last_block, block)
def test_is_valid_block_bad_last_hash(last_block, block): # last_block = Block.genesis() # block = Block.mine_block(last_block, 'test-block') block.last_hash = "corrupted_last_hash" with pytest.raises(Exception, match='last_hash must be correct.'): Block.is_valid_block(last_block, block)
def test_is_valid_block_tampered_hash(prev_block, block): correct_hash = block.hash block.hash = "0000000000000000000000000000000000000facada" with pytest.raises( Exception, match=f"hash mismatch got: {block.hash} want: {correct_hash}"): Block.is_valid_block(prev_block, block)
def test_is_valid_block_bad_block_hash(last_block, block): # Change the hash in a sneak way adding leading zeros to trick proof of work requirement block.hash = "00000000000000000000bbbabc" # Expecting an exception to be thrown with exact match for exception message with pytest.raises(Exception, match="block hash must be correct"): Block.is_valid_block(last_block, block)
def test_is_valid_block_bad_block(last_block, block): block.hash = ("0" * block.difficulty) with pytest.raises( Exception, match='must be a valid combination of the block fields'): Block.is_valid_block(last_block, block)
def test_is_valid_block_wrong_difficulty(last_block, block): block.difficulty = last_block.difficulty + 3 block.hash = f'{"0" * (last_block.difficulty + 3)}abc111' with pytest.raises(Exception, match='Block difficulty must only adjust by 1'): Block.is_valid_block(last_block, block)
def test_is_valid_block_bad_last_hash(): last_block = Block.genesis() block = Block.mine_block(last_block, 'test') block.last_hash = 'bad_last_hash' with pytest.raises(Exception, match='last_hash must be correct'): 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 equal to last_block.hash'): Block.is_valid_block(last_block, block)
def test_is_valid_block_bad_proof_of_work(last_block, block): # Edit the hash to manually trigger bad data block.hash = "fff" # Expecting an exception to be thrown with exact match for exception message with pytest.raises(Exception, match="proof of work requirement was not met"): Block.is_valid_block(last_block, block)
def test_is_valid_block_jumped_difficulty(last_block, block): jumped_difficulty = 10 block.difficulty = jumped_difficulty block.hash = f"{'0'*jumped_difficulty}1c21a" with pytest.raises( Exception, match='Block difficulty must only increase/decrease by 1.'): Block.is_valid_block(last_block, block)
def test_is_valid_block_bad_last_hash(last_block, block): block.last_hash = 'manipulated_hash' with pytest.raises( Exception, match= 'The block last_hash does not equal the last_blocks hash value.'): Block.is_valid_block(last_block, block)
def test_is_valid_block_jumped_difficulty(last_block, block): jumped_difficulty = 10 block.difficulty = jumped_difficulty block.hash = f'{"0" * jumped_difficulty}123abc' with pytest.raises(Exception, match='The block difficulty is not within 1'): Block.is_valid_block(last_block, block)
def test_is_valid_block_jumped_difficulty(last_block, block): block.difficulty = 10 block.hash = f'{"0" * block.difficulty}111abc' with raises( Exception, match='The block difficulty must only increase/decrease by one'): Block.is_valid_block(last_block, block)
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 was not met. The block"s hash does not have leading zeros equal to the difficulty' ): Block.is_valid_block(last_block, block)
def test_is_valid_block_jumped_difficulty(last_block, block): jumped_difficulty = 10 block.difficulty = jumped_difficulty block.hash = f'{"0" * jumped_difficulty}' with pytest.raises(Exception, match='Difficulty adjusted by more than one degree.'): Block.is_valid_block(last_block, block)
def test_is_valid_block_jumped_difficulty(last_block, block): jumped_difficulty = 10 block.difficulty = jumped_difficulty block.hash = f'{"0" *jumped_difficulty}aa112' #Below code allows to catch exceptions with pytest.raises(Exception, match='Block difficulty must be adjusted by 1 only.'): Block.is_valid_block(last_block, block)
def test_is_valid_jumped_difficulty(last_block, block): jd = 10 block.difficulty = jd block.hash = f'{"0"*jd}111abc' with pytest.raises( Exception, match='The block difficulty must only be adjusted by 1'): Block.is_valid_block(last_block, block)
def is_valid_chain(chain): if chain[0] != Block.genesis(): 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) Blockchain.is_valid_transaction_chain(chain)
def test_is_valid_block_bad_difficulty(last_block, block): jumped_difficulty = 8 block.difficulty = jumped_difficulty block.hash = f"{'0'*jumped_difficulty}abbbd112333" with pytest.raises( Exception, match="The difficulty requirement was altered by more than 1."): Block.is_valid_block(last_block, block)
def test_is_valid_block_jumped_difficulty(last_block, block): jumped_difficulty = 10 block.difficulty = jumped_difficulty # Set the hash to have correct amount of leading zeros with the increased difficulty block.hash = f'{"0" * jumped_difficulty}111abc' # Expecting an exception to be thrown with exact match for exception message with pytest.raises(Exception, match="difficulty must only adjust by 1"): Block.is_valid_block(last_block, block)
def test_is_valid_block_jumped_difficulty(last_block, block): jumped_difficulty = 10 block.difficulty = jumped_difficulty block.hash = f'{"0" * jumped_difficulty}111abc' # requires this step otherwise above exception for 'bad proof of work' would raise with pytest.raises( Exception, match='The block difficulty must only be adjusted by 1'): Block.is_valid_block(last_block, block)
def test_is_valid_block_bad_hash(last_block, block): # Leading this hash with all zero's allows us to pass the proof-of-work concepts # Truly tests the last line of defense against our corrupted data by ensuring our check on the hash on our side. block.hash = '000000000000000000000bbbabc' with pytest.raises( Exception, match='The block hash must be correct. Data was corrupted/tampered' ): Block.is_valid_block(last_block, block)
def is_valid_chain(chain): # Validate the incoming chain # Enforce following rules # - chain must start with the genesis block # - blocks must be formatted correctly if chain[0] != Block.genesis(): 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 is_valid_chain(chain): """ Validate the incoming chain with respect to the following rules: - the chain must start with the genesis block - each block must be formatted correctly """ if chain[0] != Block.genesis(): raise Exception("Invalid genesis block") for i in range (1, len(chain)): block = chain[i] last_block = chain[i-1] Block.is_valid_block(last_block, block)
def is_valid_chain(chain): """ Validate a chain: - must start with the genesis block - every block must be valid """ if chain[0] != Block.genesis(): raise Exception("genesis block is invalid") for i in range(1, len(chain)): current_block = chain[i] previous_block = chain[i - 1] Block.is_valid_block(previous_block, current_block)