Verify that a preorder of a name at a particular block number is well-formed

    NOTE: these *can't* be incorporated into namespace-imports,
    since we have no way of knowning which namespace the
    nameop belongs to (it is blinded until registration).
    But that's okay--we don't need to preorder names during
    a namespace import, because we will only accept names
    sent from the importer until the NAMESPACE_REVEAL operation
    is sent.

    Return True if accepted
    Return False if not.

def check( state_engine, nameop, block_id, checked_ops ):
    """
    Verify that a preorder of a name at a particular block number is well-formed

    NOTE: these *can't* be incorporated into namespace-imports,
    since we have no way of knowning which namespace the
    nameop belongs to (it is blinded until registration).
    But that's okay--we don't need to preorder names during
    a namespace import, because we will only accept names
    sent from the importer until the NAMESPACE_REVEAL operation
    is sent.

    Return True if accepted
    Return False if not.
    """

    from .register import get_num_names_owned

    preorder_name_hash = nameop['preorder_hash']
    consensus_hash = nameop['consensus_hash']
    sender = nameop['sender']

    token_fee = nameop['token_fee']
    token_type = nameop['token_units']
    token_address = nameop['address']

    # must be unique in this block
    # NOTE: now checked externally in the @state_preorder decorator

    # must be unique across all pending preorders
    if not state_engine.is_new_preorder( preorder_name_hash ):
        log.warning("Name hash '%s' is already preordered" % preorder_name_hash )
        return False

    # must have a valid consensus hash
    if not state_engine.is_consensus_hash_valid( block_id, consensus_hash ):
        log.warning("Invalid consensus hash '%s'" % consensus_hash )
        return False

    # sender must be beneath quota
    num_names = get_num_names_owned( state_engine, checked_ops, sender ) 
    if num_names >= MAX_NAMES_PER_SENDER:
        log.warning("Sender '%s' exceeded name quota of %s" % (sender, MAX_NAMES_PER_SENDER ))
        return False 

    # burn fee must be present
    if not 'op_fee' in nameop:
        log.warning("Missing preorder fee")
        return False

    epoch_features = get_epoch_features(block_id)
    if EPOCH_FEATURE_NAMEOPS_COST_TOKENS in epoch_features and token_type is not None and token_fee is not None:
        # does this account have enough balance?
        account_info = state_engine.get_account(token_address, token_type)
        if account_info is None:
            log.warning("No account for {} ({})".format(token_address, token_type))
            return False

        account_balance = state_engine.get_account_balance(account_info)

        assert isinstance(account_balance, (int,long)), 'BUG: account_balance of {} is {} (type {})'.format(token_address, account_balance, type(account_balance))
        assert isinstance(token_fee, (int,long)), 'BUG: token_fee is {} (type {})'.format(token_fee, type(token_fee))

        if account_balance < token_fee:
            # can't afford 
            log.warning("Account {} has balance {} {}, but needs to pay {} {}".format(token_address, account_balance, token_type, token_fee, token_type))
            return False

        # must be the black hole address, regardless of namespace version (since we don't yet support pay-stacks-to-namespace-creator)
        if nameop['burn_address'] != BLOCKSTACK_BURN_ADDRESS:
            # not sent to the right address
            log.warning('Preorder burned to {}, but expected {}'.format(nameop['burn_address'], BLOCKSTACK_BURN_ADDRESS))
            return False

        # for now, this must be Stacks
        if nameop['token_units'] != TOKEN_TYPE_STACKS:
            # can't use any other token (yet)
            log.warning('Preorder burned unrecognized token unit "{}"'.format(nameop['token_units']))
            return False

        # debit this account when we commit
        state_preorder_put_account_payment_info(nameop, token_address, token_type, token_fee)
        
        # NOTE: must be a string, to avoid overflow
        nameop['token_fee'] = '{}'.format(token_fee)

    else:
        # not paying in tokens, but say so!
        state_preorder_put_account_payment_info(nameop, None, None, None)
        nameop['token_fee'] = '0'
        nameop['token_units'] = 'BTC'

    return True