Exemple #1
0
 def test_block_is_valid_hashes_validation_error(self):
     self.first_block.hash = '1nval1d ha57'
     err_message = (f'Block {self.first_block.index} hash "{self.first_block.hash}" and '
                    f'block {self.second_block.index} last_hash "{self.second_block.last_hash}" must match.')
     with self.assertRaises(BlockError) as err:
         Block.is_valid(self.first_block, self.second_block)
         self.assertIn(err_message, err.message)
Exemple #2
0
 def test_block_create_invalid_schema(self, mock_is_valid_schema):
     err_message = 'Validation error'
     mock_is_valid_schema.side_effect = Mock(side_effect=BlockError(err_message))
     with self.assertRaises(BlockError) as err:
         Block.create(**self.block_info)
         self.assertTrue(mock_is_valid_schema.called)
         self.assertIsInstance(err, BlockError)
         self.assertIn(err_message, err.message)
Exemple #3
0
 def test_block_is_valid_difficulty_validation_error(self):
     self.first_block.difficulty = 10
     err_message = ('Difficulty must differ as much by 1 between blocks: '
                   f'block {self.second_block.index} difficulty: {self.second_block.difficulty}, '
                   f'block {self.first_block.index} difficulty: {self.first_block.difficulty}.')
     with self.assertRaises(BlockError) as err:
         Block.is_valid(self.first_block, self.second_block)
         self.assertIn(err_message, err.message)
Exemple #4
0
 def test_block_mine_block(self, mock_proof_of_work, mock_is_valid_schema):
     mock_is_valid_schema.return_value = True
     mock_proof_of_work.return_value = self.block_info
     block = Block.mine_block(self.first_block, self.second_block.data)
     self.assertTrue(mock_is_valid_schema.called)
     self.assertTrue(mock_proof_of_work.called)
     self.assertIsInstance(block, Block)
Exemple #5
0
 def test_block_create_valid_schema(self, mock_is_valid_schema):
     mock_is_valid_schema.return_value = True
     block = Block.create(**self.block_info)
     self.assertTrue(mock_is_valid_schema.called)
     self.assertIsInstance(block, Block)
     self.assertTrue(all([attr in block.info.keys() for attr in self.block_info.keys()]))
     self.assertTrue(all([value in block.info.values() for value in self.block_info.values()]))
Exemple #6
0
    def __init__(self, chain: list = None):
        """
        Create a new Blockchain instance.

        :param list chain: chain of blocks.
        """
        self.chain = chain or [Block.genesis()]
Exemple #7
0
 def test_block_proof_of_work(self, mock_adjust_difficulty, mock_is_valid_schema):
     mock_is_valid_schema.return_value = True
     mock_adjust_difficulty.return_value = self.first_block.difficulty + 1
     block = Block.mine_block(self.first_block, self.second_block.data)
     self.assertTrue(mock_is_valid_schema.called)
     self.assertTrue(mock_adjust_difficulty.called)
     self.assertIsInstance(block, Block)
Exemple #8
0
    def deserialize(cls, chain: list):
        """
        Create a new Blockchain instance from the provided serialized chain.

        :param list chain: serialized chain of blocks.
        :return Blockchain: blockchain created from provided stringified chain.
        """
        chain = list(map(lambda block: Block.deserialize(block), chain))
        return cls(chain)
Exemple #9
0
 def test_api_get_mine_block_route(self, mock_clear_pool,
                                   mock_broadcast_chain):
     mock_broadcast_chain.return_value = asyncio.Future()
     mock_broadcast_chain.return_value.set_result(None)
     mock_clear_pool.return_value = True
     response = self.client.get("/mine")
     self.assertTrue(mock_broadcast_chain.called)
     self.assertTrue(mock_clear_pool.called)
     self.assertEqual(response.status_code, 200)
     self.assertIn('block', response.json())
     block_info = response.json().get('block')
     self.assertEqual(Block.create(**block_info), app.blockchain.last_block)
Exemple #10
0
    def add_block(self, data: list):
        """
        Mine new block and add it to the local blockchain. If new block
        is mined the candidate blockchain will be send over the network
        to be validated for the rest of the nodes.

        :param data list: transactions data to be added to the next block.
        :return Block: new mined block.
        """
        block = Block.mine_block(self.last_block, data)
        self.chain.append(block)
        return block
Exemple #11
0
    def valid_chain(cls, value: list):
        """
        Validate chain items values.

        :param list value: provided chain value.
        :return list: validated chain value.
        :raise ValueError: on invalid block in chain.
        """
        genesis = last_block = value[0]
        if not isinstance(genesis, Block) or genesis != Block.genesis():
            message = f'Invalid chain genesis block: {genesis}.'
            logger.error(f'[BlockchainSchema] Validation error. {message}')
            raise ValueError(message)
        for block in value[1:]:
            try:
                assert isinstance(block, Block)
                Block.is_valid(last_block, block)
            except (AssertionError, BlockError) as err:
                message = err.message if hasattr(err, 'message') else f'Invalid block: {block}.'
                logger.error(f'[BlockchainSchema] Validation error. {message}')
                raise ValueError(message)
            last_block = block
        return value
Exemple #12
0
 def test_block_deserialization(self):
     block = self.first_block.serialize()
     self.assertIsInstance(Block.deserialize(block), Block)
Exemple #13
0
 def _generate_block(self, block: Block, mock_is_valid_schema):
     mock_is_valid_schema.return_value = True
     transaction = self._generate_transaction()
     data = [transaction.info]
     return Block.mine_block(block, data)
Exemple #14
0
 def test_block_adjust_difficulty_decrease(self):
     self.second_block.timestamp = 10
     difficulty = Block.adjust_difficulty(self.second_block, get_utcnow_timestamp())
     self.assertEqual(difficulty, self.second_block.difficulty - 1)
Exemple #15
0
 def test_block_is_valid(self):
     Block.is_valid(self.first_block, self.second_block)
Exemple #16
0
 def test_block_adjust_difficulty_increase(self):
     self.second_block.timestamp = 10
     difficulty = Block.adjust_difficulty(self.second_block, 1)
     self.assertEqual(difficulty, self.second_block.difficulty + 1)
Exemple #17
0
 def test_block_is_valid_schema_validation_error(self):
     self.second_block.hash = '1nval1d ha57'
     with self.assertRaises(BlockError) as err:
         Block.is_valid(self.first_block, self.second_block)
         self.assertIsInstance(err, BlockError)
         self.assertIn('Validation error', err.message)
Exemple #18
0
 def test_block_adjust_difficulty_set_to_one(self):
     self.second_block.timestamp = 1
     difficulty = Block.adjust_difficulty(self.second_block, get_utcnow_timestamp())
     self.assertEqual(difficulty, 1)
Exemple #19
0
 def _get_genesis_block(self):
     return Block.genesis()