Exemple #1
0
    def test_fork_grow_no_reconverge(self):
        stream = open(self.chain.blk_files[0], 'r')

        # Mock reconverge method
        self.chain.reconverge = MagicMock()

        # Add one block
        block1 = self.chain.handle_stream_block(BlockFactory.from_stream(stream)['block'])

        # Add 10 blocks to the main chain
        for i in range(10):
            self.chain.handle_stream_block(BlockFactory.from_stream(stream)['block'])

        # simulate fork
        block2 = BlockFactory.from_stream(stream)['block']
        block2.previousblockhash = block1.hash
        added = self.chain.handle_stream_block(block2)
        # make sure its not on the main chain
        self.assertNotEqual(added.chain, MAIN_CHAIN)

        self.chain.db.update_block = MagicMock()

        # simulate fork grow
        block3 = BlockFactory.from_stream(stream)['block']
        block3.previousblockhash = block2.hash
        added = self.chain.handle_stream_block(block3)
        # check if it belongs to the same sidechain as block2
        self.assertEqual(added.chain, block2.chain)

        self.assertTrue(self.chain.db.update_block.called)

        # Reconverge shouldn't be called
        self.assertFalse(self.chain.reconverge.called)
Exemple #2
0
    def test_fork_grow_reconverge(self):
        stream = open(self.chain.blk_files[0], 'r')

        # Add one block
        block1 = self.chain.handle_stream_block(BlockFactory.from_stream(stream)['block'])

        # Add the second block (we'll use it to check if reconverge worked)
        block2 = self.chain.handle_stream_block(BlockFactory.from_stream(stream)['block'])

        # Make sure it's initially on the main chain
        self.assertEqual(block2.chain, MAIN_CHAIN)

        # Add 10 blocks to the main chain
        for i in range(10):
            self.chain.handle_stream_block(BlockFactory.from_stream(stream)['block'])

        # Simulate fork on block1
        block3 = BlockFactory.from_stream(stream)['block']
        block3.previousblockhash = block1.hash
        added = self.chain.handle_stream_block(block3)
        self.assertNotEqual(added.chain, MAIN_CHAIN)

        # Simulate fork grow and reconverge
        block4 = BlockFactory.from_stream(stream)['block']
        block4.previousblockhash = block3.hash
        block4.work += 10000000
        added = self.chain.handle_stream_block(block4)

        # After the reconverge the added block should be on the main chain
        self.assertEqual(added.chain, MAIN_CHAIN)
        # And it should be the tip of the main chain
        self.assertEqual(added.hash, self.chain.chain_peak.hash)
        # Block2 should not be on the main chain any more
        self.assertNotEqual(self.chain.db.get_block(block2.hash).chain, MAIN_CHAIN)
Exemple #3
0
    def test_fork_reconverge(self):
        # Create 3 blocks
        stream = open(self.chain.blk_files[0], 'r')
        block1 = BlockFactory.from_stream(stream)['block']
        block2 = BlockFactory.from_stream(stream)['block']
        block3 = BlockFactory.from_stream(stream)['block']

        # Simulate fork - the 3rd block now points to the 1st
        # instead to the 2nd block so it forks from the main chain
        block3.previousblockhash = block1.hash

        # Increase work so reconverge happens
        block3.work = block3.work + 1000000000

        self.chain.handle_stream_block(block1)
        added = self.chain.handle_stream_block(block2)

        # Block2 should initially be on the main chain
        self.assertEqual(added.chain, MAIN_CHAIN)

        added = self.chain.handle_stream_block(block3)
        # After the reconverge the newest block should be on the main chain
        self.assertEqual(added.chain, MAIN_CHAIN)

        # And it should be the tip of the main chain
        self.assertEqual(self.chain.chain_peak.hash, block3.hash)

        # After the reconverge block2 should be on a sidechain
        self.assertNotEqual(self.chain.db.get_block(block2.hash), MAIN_CHAIN)

        self.assertEqual(self.chain.num_convergences, 1)

        self.assertEqual(len(self.chain.db.block_cache), 2)
Exemple #4
0
    def test_fork_no_reconverge(self):
        # Create 3 blocks
        stream = open(self.chain.blk_files[0], 'r')
        block1 = BlockFactory.from_stream(stream)['block']
        block2 = BlockFactory.from_stream(stream)['block']
        block3 = BlockFactory.from_stream(stream)['block']

        # Mock reconverge method
        self.chain.reconverge = MagicMock()

        # Simulate fork - the 3rd block now points to the 1st
        # instead to the 2nd block so it forks from the main chain
        block3.previousblockhash = block1.hash

        self.chain.handle_stream_block(block1)
        self.chain.handle_stream_block(block2)

        added = self.chain.handle_stream_block(block3)

        # The added block should not be on the main chain
        self.assertEqual(added.chain, MAIN_CHAIN + 1)
        self.assertEqual(added.height, block1.height + 1)

        # Reconverge shouldn't be called
        self.assertFalse(self.chain.reconverge.called)
Exemple #5
0
    def test_append_to_main_chain(self):
        self.chain.db.put_block = MagicMock()

        stream = open(self.chain.blk_files[0], 'r')
        block1 = BlockFactory.from_stream(stream)['block']
        block2 = BlockFactory.from_stream(stream)['block']
        self.chain.handle_stream_block(block1)
        added_block = self.chain.handle_stream_block(block2)

        self.assertEqual(added_block.height, block1.height + 1)
        self.assertEqual(added_block.chainwork, block1.chainwork + block2.work)
        self.assertEqual(added_block.chain, 0)
        self.assertEqual(self.chain.chain_peak.hash, block2.hash)

        # Persistence check
        self.assertEqual(self.chain.db.put_block.call_count, 1)
    def test_from_stream(self):
        stream = open('test_data/blk00001.dat', 'r')
        block = BlockFactory.from_stream(stream)

        self.assertIsNotNone(block)
        self.assertIsNotNone(block.bits)
        self.assertIsNone(block.chain)
        self.assertIsNone(block.chainwork)
        self.assertIsNotNone(block.dat)
        self.assertIsNotNone(block.difficulty)
        self.assertIsNotNone(block.hash)
        self.assertIsNone(block.height)
        self.assertIsNotNone(block.merkleroot)
        self.assertIsNone(block.nextblockhash)
        self.assertIsNotNone(block.nonce)
        self.assertIsNotNone(block.previousblockhash)
        self.assertIsNotNone(block.size)
        self.assertIsNotNone(block.target)
        self.assertIsNotNone(block.time)
        self.assertIsNotNone(block.total)
        self.assertIsNotNone(block.tx)
        self.assertIsNotNone(block.version)
        self.assertIsNotNone(block.work)

        for tr in block.tx:
            self._check_transaction(tr)
            for vin in tr.vin:
                self._check_vin(vin)

            for vout in tr.vout:
                self._check_vout(vout)
    def test_from_rpc(self):
        with open('test_data/rpc_data.json') as json_data:
            data = simplejson.load(json_data)
            block = BlockFactory.from_rpc(data['block'], data['transactions'])
            self.assertIsNotNone(block)
            self.assertIsNotNone(block.bits)
            self.assertIsNone(block.chain)
            self.assertIsNotNone(block.chainwork)
            self.assertIsNone(block.dat)
            self.assertIsNotNone(block.difficulty)
            self.assertIsNotNone(block.hash)
            self.assertIsNotNone(block.height)
            self.assertIsNotNone(block.merkleroot)
            self.assertIsNotNone(block.nextblockhash)
            self.assertIsNotNone(block.nonce)
            self.assertIsNotNone(block.previousblockhash)
            self.assertIsNotNone(block.size)
            self.assertIsNotNone(block.target)
            self.assertIsNotNone(block.time)
            self.assertIsNotNone(block.total)
            self.assertIsNotNone(block.tx)
            self.assertIsNotNone(block.version)
            self.assertIsNotNone(block.work)

            for tr in block.tx:
                self._check_transaction(tr)
                for vin in tr.vin:
                    self._check_vin(vin)

                for vout in tr.vout:
                    self._check_vout(vout)
Exemple #8
0
    def setUp(self):
        self.db = MagicMock()

        self.example_block = BlockFactory.from_mongo(EXAMPLE_MONGO_BLOCK)
        self.db.blocks.find_one = MagicMock(return_value=EXAMPLE_MONGO_BLOCK)
        self.chain = ExploderSyncer(
            database=self.db,
            blocks_dir="/home/vagrant/.gamecredits/blocks/",
            rpc_client=MagicMock()
        )
        self.db.blocks.create_index = MagicMock()
        self.SYNC_LIMIT = 100
Exemple #9
0
    def setUp(self):
        self.fake_mongo = MagicMock()
        self.fake_mongo.blocks.find_one.return_value = None

        self.fake_rpc = MagicMock()
        self.fake_rpc.getblockcount = MagicMock(return_value=10000)

        self.db = DatabaseGateway(database=self.fake_mongo, cache_size=1000)
        self.db.highest_block = PropertyMock(return_value=None)

        self.chain = ExploderSyncer(
            database=self.db,
            blocks_dir="/home/vagrant/.gamecredits/blocks/",
            rpc_client=self.fake_rpc
        )

        self.example_block = BlockFactory.from_mongo(EXAMPLE_MONGO_BLOCK)