Пример #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)
Пример #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)
Пример #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)
Пример #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)
Пример #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()]))
Пример #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()]
Пример #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)
Пример #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)
Пример #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)
Пример #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
Пример #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
Пример #12
0
 def test_block_deserialization(self):
     block = self.first_block.serialize()
     self.assertIsInstance(Block.deserialize(block), Block)
Пример #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)
Пример #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)
Пример #15
0
 def test_block_is_valid(self):
     Block.is_valid(self.first_block, self.second_block)
Пример #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)
Пример #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)
Пример #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)
Пример #19
0
 def _get_genesis_block(self):
     return Block.genesis()