def is_block_valid(prev_block, block):
        """
        Validate each block by enforcing the following ruleset:
            - block must have proper prev_hash ref
            - block must meet proof of work requirement
            - difficulty must have adjusted by 1
            - the block has must be a valid aggregate of block fields
        """
        if (block.prev_hash != prev_block.hash):
            raise Exception("Value previous hash is invalid.")
        if (hex_to_binary(block.hash)[0:block.difficulty] !=
                "0" * block.difficulty):
            raise Exception(
                "Value error. A Proof of Work requirement has not been met.")
        if (abs(prev_block.difficulty - block.difficulty) > 1):
            raise Exception("Difficulty adjustment error.")

        reconstructed_hash = generate_hash(
            block.timestamp,
            block.prev_hash,
            block.data,
            block.difficulty,
            block.nonce,
        )
        if (block.hash != reconstructed_hash):
            raise Exception(
                "Value error. A Proof of Work requirement has not been met.")
def test_hex_to_binary():
    num = 879
    hex_num = hex(num)[2:]
    binary_num = hex_to_binary(hex_num)

    # It should be a binary int
    assert int(binary_num, 2)
示例#3
0
    def is_valid_block(last_block, block):
        """
        Validate block by enforcing the following rules:
            - The block's last_hash must be equal to last_block's hash
            - The block must meet the proof of work requirement
            - The difficulty must only adjust by 1 (decrease or increase)
            - The block hash must be a valid combination of the block's fields
        """
        # Rule 1: The block's last hash must be equal to last_block's hash
        if block.last_hash != last_block.hash:
            raise Exception('The block last_hash must be correct')

        # Rule 2: The block must meet the proof of work requirement
        if hex_to_binary(
                block.hash)[0:block.difficulty] != '0' * block.difficulty:
            raise Exception('The proof of work requirement was not met')

        # Rule 3: The difficulty must only adjust by 1
        if abs(last_block.difficulty - block.difficulty) > 1:
            raise Exception('The difficulty must only adjust by 1')

        # Rule 4: The block hash must be a valid combination of the block's fields
        reconstructed_hash = crypto_hash(block.timestamp, block.last_hash,
                                         block.data, block.difficulty,
                                         block.nonce)

        if block.hash != reconstructed_hash:
            raise Exception('The block hash must be correct')
示例#4
0
def test_mine_block():
    last_block = Block.genesis()
    data = 'test-data'
    block = Block.mine_block(last_block, data)

    assert isinstance(block, Block)
    assert block.data == data
    assert block.lasthash == last_block.hash
    assert hex_to_binary(
        block.hash)[0:block.difficulty] == '0' * block.difficulty
def test_mine_block():
    prev_block = Block.genesis()
    data = "test"
    block = Block.mine_block(prev_block, data)

    assert isinstance(block, Block)
    assert block.data == data
    assert block.prev_hash == prev_block.hash
    assert hex_to_binary(
        block.hash)[0:block.difficulty] == "0" * block.difficulty
def test_mine_block(last_block, mined_block):
    assert isinstance(last_block, Block)
    assert isinstance(mined_block, Block)
    #verify the genesis block
    for key, value in GENESIS_BLOCK.items():
        assert getattr(last_block, key) == value
    data = "sample_data"
    assert mined_block.data == data
    assert mined_block.last_hash == last_block.hash
    assert hex_to_binary(
        mined_block.hash[2:])[0:mined_block.
                              difficulty] == '0' * mined_block.difficulty
    def mine_block(prev_block, data):
        timestamp = time.time_ns()
        prev_hash = prev_block.hash
        difficulty = Block.adjust_difficulty(prev_block, timestamp)
        nonce = 0
        hash = generate_hash(timestamp, prev_hash, data, difficulty, nonce)

        while (hex_to_binary(hash)[0:difficulty] != "0" * difficulty):
            nonce += 1
            timestamp = time.time_ns()
            difficulty = Block.adjust_difficulty(prev_block, timestamp)
            hash = generate_hash(timestamp, prev_hash, data, difficulty, nonce)
        return Block(timestamp, prev_hash, hash, data, difficulty, nonce)
示例#8
0
 def is_block_valid(last_block, block):
     """
     Check if the block is valid
     """
     if block.last_hash != last_block.hash:
         raise Exception(
             "The last block hash and the last hash of the new block should match"
         )
     if hex_to_binary(
             block.hash)[0:block.difficulty] != "0" * block.difficulty:
         raise Exception("Proof of work requirement not met")
     if abs(last_block.difficulty - block.difficulty) > 1:
         raise Exception('The block difficulty must only adjust by 1')
     rebuilded_hash = crypto_hash(block.timestamp, block.last_hash,
                                  block.data, block.difficulty, block.nonce)
     if block.hash != rebuilded_hash:
         raise Exception(f"The hash of the block: {block.hash} is invalid")
示例#9
0
    def mine_block(last_block, data):
        """
        Mines a block based on the given last_block and data until a block hash is found that meets the leading 0's proof of work requirement.
        """
        timestamp = time.time_ns()
        lasthash = last_block.hash
        difficulty = Block.adjust_difficulty(last_block, timestamp)
        nonce = 0
        hash = crypto_hash(timestamp, lasthash, data, difficulty, nonce)

        while hex_to_binary(hash)[0:difficulty] != '0' * difficulty:
            nonce += 1
            timestamp = time.time_ns()
            difficulty = Block.adjust_difficulty(last_block, timestamp)
            hash = crypto_hash(timestamp, lasthash, data, difficulty, nonce)

        return Block(timestamp, lasthash, hash, data, difficulty, nonce)
示例#10
0
    def mine_block(last_block, data):
        """
        Mine a block with the details of last block and the data of the block to be created.
        Hash of the new block to be created should match the proof of work requirement of leading zeros.

        """
        timestamp = time.time_ns()
        last_hash = last_block.hash
        difficulty = Block.adjust_difficulty(last_block, timestamp)
        nonce = 0
        hash = crypto_hash(timestamp, last_hash, data, difficulty, nonce)

        while hex_to_binary(hash)[0:difficulty] != '0' * difficulty:
            nonce += 1
            timestamp = time.time_ns()
            difficulty = Block.adjust_difficulty(last_block, timestamp)
            hash = crypto_hash(timestamp, last_hash, data, difficulty, nonce)

        return Block(timestamp, hash, last_hash, data, difficulty, nonce)
示例#11
0
    def mine_block(last_block, data):
        """
		Static method to mine a block
		"""
        last_hash = last_block.hash
        timestamp = time.time_ns()
        nonce = 0
        difficulty = Block.adjust_difficulty(last_block, timestamp)
        #Make the nonce calculation even more challenging by converting SHA-256 hash to binary
        #start from 3rd character in hexadecimal representation to remove the 0x
        hash = crypto_hash.crypto_hash(timestamp, last_hash, difficulty, nonce,
                                       data)
        while hex_to_binary(hash[2:])[0:difficulty] != '0' * difficulty:
            nonce = nonce + 1
            timestamp = time.time_ns()
            difficulty = Block.adjust_difficulty(last_block, timestamp)
            hash = crypto_hash.crypto_hash(timestamp, last_hash, difficulty,
                                           nonce, data)
        return Block(timestamp, hash, last_hash, difficulty, nonce, data)
示例#12
0
    def is_block_valid(last_block, block):
        """
		Method to check if a given block is valid.
		Block is valid if:
		1. Last hash of block is equal to hash of last_block.
		2. Hash of the block meets the proof of work requirement.
		3. Block difficulty must not vary by more than 1 unit.
		4. Hash of the block is equal to the hash which is generated again.
		"""
        if block.last_hash != last_block.hash:
            raise Exception("The hash of last block did not match")
        if hex_to_binary(
                block.hash[2:])[0:block.difficulty] != "0" * block.difficulty:
            raise Exception("The proof of work requirement was not met")
        if abs(block.difficulty - last_block.difficulty) > 1:
            raise Exception("The block difficulty was not valid")
        new_hash = crypto_hash.crypto_hash(block.timestamp, block.data,
                                           block.last_hash, block.difficulty,
                                           block.nonce)
        if new_hash != block.hash:
            raise Exception("The block hash was not valid")
示例#13
0
    def is_valid_block(last_block, block):
        """
        Validate block by enforcing the following rules:
        - The block must have the proper lasthash reference
        - The block must meet the proof of work requirement
        - The difficulty must only adjust by 1
        - The block hash must be a valid combination of the block fields
        """
        if block.lasthash != last_block.hash:
            raise Exception('The block lasthash must be correct')

        if hex_to_binary(
                block.hash)[0:block.difficulty] != '0' * block.difficulty:
            raise Exception('The proof of work requirement was not met')

        if abs(last_block.difficulty - block.difficulty) > 1:
            raise Exception('The block difficulty must only adjust by 1')

        reconstructed_hash = crypto_hash(block.timestamp, block.lasthash,
                                         block.data, block.nonce,
                                         block.difficulty)

        if block.hash != reconstructed_hash:
            raise Exception('The block hash must be correct')
示例#14
0
def test_hex_to_binary():
    num = 164
    binary = hex_to_binary(hex(num)[2:])
    assert num == int(binary, 2)
示例#15
0
def test_hex_to_binary():
    original_number = 789
    hex_number = hex(original_number)[2:]
    binary_number = hex_to_binary(hex_number)

    assert int(binary_number, 2) == original_number