Set up the state engine database.
        * If it doesn't exist, then create it.
        * If it does exist, then check that it is in a clean state.  If not, then recover from a known-good backup.

        Return True on success
        Return False if there was an unclean shutdown.  The caller should call db_restore() in this case to continue
        Raise exception on error
        Abort on db error

def db_setup(self):
        """
        Set up the state engine database.
        * If it doesn't exist, then create it.
        * If it does exist, then check that it is in a clean state.  If not, then recover from a known-good backup.

        Return True on success
        Return False if there was an unclean shutdown.  The caller should call db_restore() in this case to continue
        Raise exception on error
        Abort on db error
        """
        if self.db_exists(impl=self.impl, working_dir=self.working_dir):
            # resuming from previous indexing
            # read/write and unclean shutdown?
            if not self.read_only and self.db_is_indexing(self.impl, self.working_dir):
                log.error("Unclean shutdown detected on read/write open")
                return False
        
        else:
            # setting up for the first time
            assert not self.read_only, 'Cannot instantiate database if read_only is True'
            db_con = self.db_create(self.impl, self.working_dir)
            initial_snapshots = self.impl.get_initial_snapshots()
            for block_id in sorted(initial_snapshots.keys()):
                self.db_snapshot_append(db_con, int(block_id), str(initial_snapshots[block_id]), None, int(time.time()))

        self.chainstate_path = config.get_snapshots_filename(self.impl, self.working_dir)
        self.lastblock = self.get_lastblock(self.impl, self.working_dir)
        self.setup = True
        return True