(required by virtualchain state engine)
   
    Given the block ID and a parsed operation, check to see if this is a *valid* operation.
    Is this operation consistent with blockstack's rules?
   
    checked_ops is a list of operations already checked by
    this method for this block.
   
    A name or namespace can be affected at most once per block.  If it is 
    affected more than once, then the opcode priority rules take effect, and
    the lower priority opcodes are rejected.

    Return True if it's valid
    Return False if not.

def db_check( block_id, new_ops, op, op_data, txid, vtxindex, checked_ops, db_state=None ):
    """
    (required by virtualchain state engine)
   
    Given the block ID and a parsed operation, check to see if this is a *valid* operation.
    Is this operation consistent with blockstack's rules?
   
    checked_ops is a list of operations already checked by
    this method for this block.
   
    A name or namespace can be affected at most once per block.  If it is 
    affected more than once, then the opcode priority rules take effect, and
    the lower priority opcodes are rejected.

    Return True if it's valid
    Return False if not.
    """

    accept = True 

    if db_state is not None:
        
        try:
            assert 'txid' in op_data, "Missing txid from op"
            assert 'vtxindex' in op_data, "Missing vtxindex from op"
            opcode = op_get_opcode_name( op )
            assert opcode is not None, "BUG: unknown op '%s'" % op
        except Exception, e:
            log.exception(e)
            log.error("FATAL: invalid operation")
            os.abort()

        log.debug("CHECK %s at (%s, %s)" % (opcode, block_id, vtxindex))
        rc = op_check( db_state, op_data, block_id, checked_ops )
        if rc:

            try:
                opcode = op_data.get('opcode', None)
                assert opcode is not None, "BUG: op_check did not set an opcode"
            except Exception, e:
                log.exception(e)
                log.error("FATAL: no opcode set")
                os.abort()

            # verify that all mutate fields are present 
            rc = check_mutate_fields( opcode, op_data )
            if not rc:
                log.error("FATAL: bug in '%s' check() method did not return all mutate fields" % opcode)
                os.abort()

        else:
            accept = False 

    return accept