docs: def save(self, block_id, consensus_hash, ops_hash, accepted_ops, virtualchain_ops_hints, backup=False):
          """
          Write out all state to the working directory.
          Calls the implementation's 'db_save' method to store any state for this block.
          Calls the implementation's 'db_continue' method at the very end, to signal
          to the implementation that all virtualchain state has been saved.  This method
          can return False, in which case, indexing stops
          
          Return True on success 
          Return False if the implementation wants to exit.
          Aborts on fatal error
          """
          assert self.setup, "Not set up yet.  Call .db_setup() first!"
          assert len(accepted_ops) == len(virtualchain_ops_hints)
  
          if self.read_only:
              log.error("FATAL: StateEngine is read only")
              traceback.print_stack()
              os.abort()
  
          if block_id < self.lastblock:
              log.error("FATAL: Already processed up to block {} (got {})".format(self.lastblock, block_id))
              traceback.print_stack()
              os.abort()
          
          # ask the implementation to save 
          if hasattr(self.impl, 'db_save'):
              rc = False
              try:
                  rc = self.impl.db_save(block_id, consensus_hash, ops_hash, accepted_ops, virtualchain_ops_hints, db_state=self.state)
              except Exception as e:
                  log.exception(e)
                  rc = False
  
              if not rc:
                  log.error("FATAL: Implementation failed to save state at block {}".format(block_id))
                  traceback.print_stack()
                  os.abort()
  
          # save new chainstate
          self.lastblock = block_id
  
          # start a transaction to store the new data
          db_con = self.db_open(self.impl, self.working_dir)
          cur = db_con.cursor()
  
          self.db_query_execute(cur, "BEGIN", (), verbose=False)
          
          # add chainstate
          for i, (accepted_op, virtualchain_op_hints) in enumerate(zip(accepted_ops, virtualchain_ops_hints)):
  
              # unpack virtualchain hints
              senders = virtualchain_op_hints['virtualchain_senders']
              data_hex = virtualchain_op_hints['virtualchain_data_hex']
              tx_hex = virtualchain_op_hints['virtualchain_txhex']
              txid = virtualchain_op_hints['virtualchain_txid']
              fee = virtualchain_op_hints['virtualchain_fee']
              opcode = virtualchain_op_hints['virtualchain_opcode']
              txindex = virtualchain_op_hints['virtualchain_txindex']
              vtxindex = i
              merkle_path = virtualchain_op_hints['virtualchain_tx_merkle_path']
  
              vtx_data = {
                  'txid': txid,
                  'senders': simplejson.dumps(senders),
                  'data_hex': data_hex,
                  'tx_hex': tx_hex,
                  'tx_merkle_path': merkle_path,
                  'fee': fee,
                  'opcode': opcode,
                  'txindex': txindex,
                  'vtxindex': vtxindex,
                  'block_id': block_id
              }
              
              self.db_chainstate_append(cur, **vtx_data)
              
          # update snapshot info
          self.db_snapshot_append(cur, block_id, consensus_hash, ops_hash, int(time.time()))
          self.db_query_execute(cur, "END", (), verbose=False)
          db_con.close()
  
          # make new backups and clear old ones
          self.make_backups(block_id)
          self.clear_old_backups(block_id)
          
          # ask the implementation if we should continue
          continue_indexing = True
          if hasattr(self.impl, "db_continue"):
              try:
                  continue_indexing = self.impl.db_continue( block_id, consensus_hash )
              except Exception, e:
                  log.exception(e)
                  traceback.print_stack()
                  log.error("FATAL: implementation failed db_continue")
                  os.abort()
  
          return continue_indexing