Esempio n. 1
0
    def test_access_wallet_with_bad_data(self):
        '''
            Test access wallet with bad data
        '''
        MINUTE = 60
        WAIT_SECONDS = 10
        MAX_SECONDS = 3 * MINUTE

        # remove a block from the blockchain
        block_filename = os.path.join(get_data_dir(), 'blocks', 'blk00000.dat')
        if os.path.exists(block_filename):
            os.remove(block_filename)

        request = self.factory.get('/bitcoin/access_wallet/')
        response = AccessWallet.as_view()(request)
        self.assertEqual(response.status_code, 200)
        self.assertTrue(
            b"<title>\nAccessing Bitcoin Core Wallet | Blockchain Backup\n</title>"
            in response.content)
        self.assertTrue(
            b"WARNING: Do not shut down your computer until Bitcoin-QT stops completely."
            in response.content)
        self.assertTrue(
            b'Bitcoin-QT will start in another window.' in response.content)
        self.assertFalse(
            b'Shutting down before this window says it is safe <em>could damage the blockchain</em>.'
            in response.content)

        done = False
        error_found = False
        error_message = None
        secs = 0
        while not done:
            shutdown, error_message = test_utils.check_bitcoin_log()
            if error_message:
                error = error_message.strip(' ')
                error_found = 'Fatal LevelDB error' in error or 'Error opening block database' in error
            done = shutdown or error_found or not get_backups_enabled(
            ) or secs > MAX_SECONDS
            if not done:
                sleep(WAIT_SECONDS)
                secs += WAIT_SECONDS

        if not error_found:
            shutdown, error_message = test_utils.check_bitcoin_log()
            self.assertTrue(shutdown)
            error = error_message.strip(' ')
            error_found = 'Fatal LevelDB error' in error or 'Error opening block database' in error
        self.assertTrue(error_found)

        test_utils.stop_bitcoin_qt()

        self.assertFalse(get_backups_enabled())
    def test_update_with_task_running(self):
        '''
            Test updating with another task running.
        '''
        # start the backup task
        request = self.factory.get('/bitcoin/backup/')
        Backup.as_view()(request)

        request = self.factory.get('/bitcoin/update/')
        response = Update.as_view()(request)

        # stop the task before we start tests in case something fails
        self.factory.get('/bitcoin/interrupt_backup/')
        InterruptBackup.as_view()(request)

        self.assertEqual(response.status_code, 200)
        self.assertTrue(
            b"<title>\nBackup Task Is Running | Blockchain Backup\n</title>" in
            response.content)
        self.assertTrue(
            b'The backup task appears to be running' in response.content)
        self.assertFalse(
            b'The update task appears to be running' in response.content)
        self.assertFalse(b'The access wallet task appears to be running' in
                         response.content)
        self.assertFalse(
            b'The restore task appears to be running' in response.content)

        self.assertTrue(get_backups_enabled())
    def test_update_with_bitcoin_d_running(self):
        '''
            Test updating with bitcoind already running.
        '''
        # start bitcoind and wait for it to get started
        test_utils.start_bitcoind()
        while not is_bitcoind_running():
            sleep(1)
        log('bitcoind is running')

        request = self.factory.get('/bitcoin/update/')
        response = Update.as_view()(request)
        self.assertEqual(response.status_code, 200)
        self.assertTrue(
            b"<title>\nBitcoinD Is Running | Blockchain Backup\n</title>" in
            response.content)
        self.assertTrue(
            b'BitcoinD, one of the Bitcoin Core programs, appears to be running'
            in response.content)
        self.assertFalse(
            b'Bitcoin-QT, one of the Bitcoin Core programs, appears to be running'
            in response.content)
        self.assertFalse(
            b'Bitcoin-TX, one of the Bitcoin Core programs, appears to be running'
            in response.content)

        if is_bitcoind_running():
            test_utils.stop_bitcoind()

        self.assertTrue(get_backups_enabled())
    def test_update_with_bad_data_dir(self):
        '''
            Test updating with a bad data directory.
        '''
        prefs = get_preferences()
        prefs.data_dir = '/bad/bitcoin/data/'
        prefs.bin_dir = '/tmp/bitcoin/bin/'
        prefs.backup_dir = '/tmp/bitcoin/data/backups/'
        save_preferences(prefs)

        request = self.factory.get('/bitcoin/update/')
        response = Update.as_view()(request)
        self.assertEqual(response.status_code, 200)
        self.assertTrue(
            b"<title>\nUpdating Bitcoin's Blockchain | Blockchain Backup\n</title>"
            in response.content)
        self.assertFalse(
            b'The Bitcoin binary directory is not valid.' in response.content)
        self.assertTrue(
            b'The Bitcoin data directory is not valid.' in response.content)
        self.assertFalse(
            b'The Bitcoin backup directory is not valid.' in response.content)
        self.assertTrue(
            b'Click <a class="btn btn-secondary" role="button" href="/bitcoin/preferences/" title="Click to change your preferences">Preferences</a> to set it.'
            in response.content)

        self.assertTrue(get_backups_enabled())
Esempio n. 5
0
    def post_page(self, request):

        backups_enabled = ('enable-backups-button' in request.POST
                           or 'leave-backups-enabled-button' in request.POST)

        if state.get_backups_enabled() != backups_enabled:
            state.set_backups_enabled(backups_enabled)
            if backups_enabled:
                messages.success(request, BACKUPS_ENABLED)
            else:
                messages.success(request, BACKUPS_DISABLED)

        # send them back to the home page
        response = HttpResponseRedirect('/')

        return response
Esempio n. 6
0
    def test_restore_with_bad_backup(self):
        '''
            Test restore from a bad back up.
        '''
        MINUTE = 60
        MAX_SECONDS = 2 * MINUTE

        # change the data and backup dirs
        prefs = test_utils.get_preferences()
        prefs.data_dir = '/tmp/bitcoin/data-with-missing-file/testnet3/'
        prefs.backup_dir = '/tmp/bitcoin/data-with-missing-file/testnet3/backups/'
        preferences.save_preferences(prefs)

        __, preselected_date_dir = state.get_backup_dates_and_dirs()

        request = self.factory.get('/bitcoin/restore/')
        response = views.Restore.as_view()(request)
        self.assertEqual(response.status_code, 200)
        self.assertTrue(b"<title>\nAre you sure you want to restore the Bitcoin blockchain? | Blockchain Backup\n</title>" in response.content)
        self.assertTrue(b'Select backup to restore:' in response.content)
        self.assertTrue(b'<input type="submit" value="Yes, start restoring" name="yes-start-restoring-button" id="yes-start-restoring-id" alt="Yes, start restoring" class="btn btn-primary font-weight-bold " role="button"  title="Restore the blockchain now"/>' in response.content)
        self.assertTrue(b'<input type="submit" value="No, cancel restore" name="no-cancel-restore-button" id="no-cancel-restore-id" alt="No, cancel restore" class="btn btn-secondary font-weight-bold " role="button"  title="Do not restore the blockchain."/>' in response.content)

        client = Client()
        response = client.post('/bitcoin/restore/',
                               {'backup_dates_with_dirs': preselected_date_dir[0] })
        self.assertEqual(response.status_code, 200)
        self.assertTrue(b"<title>\nRestoring Bitcoin Blockchain | Blockchain Backup\n</title>" in response.content)
        self.assertTrue(b'WARNING: Do not shut down your computer until the restore finishes.' in response.content)
        self.assertTrue(b'Starting to restore the blockchain' in response.content)
        self.assertFalse(b'<input type="submit" value="Yes, start restoring" name="yes-start-restoring-button" id="yes-start-restoring-id" alt="Yes, start restoring" class="btn btn-primary font-weight-bold " role="button"  title="Restore the blockchain now"/>' in response.content)

        # wait until the restore finishes
        seconds = 0
        while not is_restore_running() and seconds < MAX_SECONDS:
            sleep(MINUTE)
            seconds += MINUTE

        self.assertFalse(is_bitcoind_running())
        self.assertFalse(state.get_backups_enabled())

        name = 'last-updated-2020-01-17 14:41'
        last_updated_file = os.path.join(prefs.backup_dir, 'level1', name)
        self.assertFalse(os.path.exists(last_updated_file))
    def test_update_with_missing_links(self):
        '''
            Start the update with missing links.
        '''
        # remove links from the chainstate
        dirname = os.path.join(get_data_dir(), 'chainstate')
        entries = os.scandir(dirname)
        for entry in entries:
            if entry.name.endswith('.ldb'):
                os.remove(entry.path)

        request = self.factory.get('/bitcoin/update/')
        response = Update.as_view()(request)
        self.assertEqual(response.status_code, 200)
        self.assertTrue(
            b"<title>\nUpdating Bitcoin's Blockchain | Blockchain Backup\n</title>"
            in response.content)
        self.assertTrue(b"WARNING: Don't shut down your computer before you" in
                        response.content)
        self.assertTrue(
            b'<a class="btn btn-secondary " role="button" id="stop_button" href="/bitcoin/interrupt_update/" title="Click to stop updating the blockchain">Stop update</a>'
            in response.content)
        self.assertTrue(
            b'Shutting down before this window says it is safe <em>could damage the blockchain</em>.'
            in response.content)

        sleep(60)

        self.assertFalse(is_bitcoind_running())

        shutdown, error_message = test_utils.check_bitcoin_log(
            is_bitcoind_running)
        self.assertTrue(shutdown)
        log(error_message)
        self.assertTrue(
            'Aborted block database rebuild. Exiting.' in error_message
            or 'Error opening block database.' in error_message
            or 'Fatal LevelDB error' in error_message)

        self.assertFalse(get_backups_enabled())
Esempio n. 8
0
    def get_page(self, request):

        log('change whether backups enabled or not')

        clear_action_updates()
        form = Form()
        context = {}
        backups_enabled = state.get_backups_enabled()
        if backups_enabled:
            context[
                'header'] = 'Blockchain Backup currently backups the blockchain on your schedule.'
            context[
                'notice'] = 'WARNING: If you disable backups, then Blockchain Backup cannot keep your copy of the blockchain safe.'
            context['status'] = 'Enabled'
        else:
            context[
                'header'] = 'Blockchain Backup temporarily disabled backups the blockchain.'
            context[
                'notice'] = 'WARNING: Do <i>not</i> enable backups until Bitcoin Core runs successfully.'
            context['status'] = 'Disabled'
        context['header'] = f"Backups {context['status']}"
        context['form'] = form

        return render(request, self.form_url, context=context)
    def test_update_with_missing_blocks(self):
        '''
            Start the update with missing blocks.
        '''
        # remove a block from the blockchain
        block_filename = os.path.join(get_data_dir(), 'blocks', 'blk00000.dat')
        if os.path.exists(block_filename):
            os.remove(block_filename)

        request = self.factory.get('/bitcoin/update/')
        response = Update.as_view()(request)
        self.assertEqual(response.status_code, 200)
        self.assertTrue(
            b"<title>\nUpdating Bitcoin's Blockchain | Blockchain Backup\n</title>"
            in response.content)
        self.assertTrue(b"WARNING: Don't shut down your computer before you" in
                        response.content)
        self.assertTrue(
            b'<a class="btn btn-secondary " role="button" id="stop_button" href="/bitcoin/interrupt_update/" title="Click to stop updating the blockchain">Stop update</a>'
            in response.content)
        self.assertTrue(
            b'Shutting down before this window says it is safe <em>could damage the blockchain</em>.'
            in response.content)

        sleep(60)

        self.assertFalse(is_bitcoind_running())

        shutdown, error_message = test_utils.check_bitcoin_log(
            is_bitcoind_running)
        self.assertTrue(shutdown)
        error = error_message.strip(' ')
        error_found = 'Fatal LevelDB error' in error or 'Error opening block database' in error
        self.assertTrue(error_found)

        self.assertFalse(get_backups_enabled())
Esempio n. 10
0
    def get_page(self, request):

        global backup_task

        log('backing up blockchain')

        clear_action_updates()

        # check that no other bitcoin-core app is running
        if bitcoin_utils.is_bitcoin_core_running():
            message = NO_BACKUP_IF_CORE_RUNNING
            response = warn_core_running(request, message=message)

        # tell user if another app is running
        elif bitcoin_utils.is_restore_running():
            response = warn_bcb_app_running(request,
                                            app=constants.RESTORE_PROGRAM)

        # tell user if another task is running
        elif accessing_wallet() or updating() or restoring():
            response = warn_bcb_task_running(request)

        # tell user if backups have been disabled
        elif not state.get_backups_enabled():
            response = HttpResponseRedirect('/bitcoin/change_backup_status/')
            log('tried to backup when backups disabled')
            log(f'response: {response}')

        else:
            SUBNOTICE1 = 'If you need to stop the backup, then <a class="btn btn-secondary " href="/bitcoin/interrupt_backup/"'
            SUBNOTICE2 = 'role="button" id="stop-button" title="Click to stop backing up the blockchain">click here</a>.'
            SUBNOTICE = f'{SUBNOTICE1} {SUBNOTICE2}'

            context = bitcoin_utils.get_blockchain_context()

            data_dir_ok, error = preferences.data_dir_ok()
            if not preferences.bin_dir_ok():
                context['notice'] = BAD_BIN_DIR
                context['subnotice'] = ''
            elif not data_dir_ok:
                context['notice'] = BAD_DATA_DIR
                context['subnotice'] = error
            else:
                context['header'] = "Backing up bitcoin's blockchain"
                context[
                    'notice'] = 'WARNING: Stopping the backup could damage the ability to restore the blockchain.'
                context['subnotice'] = SUBNOTICE
                context['progress'] = 'Starting to back up the blockchain'
                context['update_interval'] = '1000'

                if backing_up():
                    log('already backing_up blockchain')

                else:
                    from blockchain_backup.bitcoin.backup import BackupTask

                    backup_task = BackupTask()
                    backup_task.start()
                    log('backup started')

            # make sure the button doesn't appear any more
            bitcoin_utils.send_socketio_message('button', ' ')

            response = render(request, 'bitcoin/backup.html', context=context)

        return response