Beispiel #1
0
def validate_subasset_longname(subasset_longname, subasset_child=None):
    if subasset_child is None:
        chunks = subasset_longname.split('.', 1)
        if (len(chunks) == 2):
            subasset_child = chunks[1]
        else:
            subasset_child = ''

    if len(subasset_child) < 1:
        raise exceptions.AssetNameError('subasset name too short')
    if len(subasset_longname) > 250:
        raise exceptions.AssetNameError('subasset name too long')

    # can't start with period, can't have consecutive periods, can't contain anything not in SUBASSET_DIGITS
    previous_digit = '.'
    for c in subasset_child:
        if c not in SUBASSET_DIGITS:
            raise exceptions.AssetNameError(
                'subasset name contains invalid character:', c)
        if c == '.' and previous_digit == '.':
            raise exceptions.AssetNameError(
                'subasset name contains consecutive periods')
        previous_digit = c
    if previous_digit == '.':
        raise exceptions.AssetNameError('subasset name ends with a period')

    return True
Beispiel #2
0
def generate_asset_id(asset_name, block_index):
    """Create asset_id from asset_name."""
    if asset_name == config.BTC: return 0
    elif asset_name == config.XCP: return 1

    if len(asset_name) < 4:
        raise exceptions.AssetNameError('too short')

    # Numeric asset names.
    if enabled('numeric_asset_names'):  # Protocol change.
        if asset_name[0] == 'A':
            # Must be numeric.
            try:
                asset_id = int(asset_name[1:])
            except ValueError:
                raise exceptions.AssetNameError(
                    'non‐numeric asset name starts with ‘A’')

            # Number must be in range.
            if not (26**12 + 1 <= asset_id <= 2**64 - 1):
                raise exceptions.AssetNameError(
                    'numeric asset name not in range')

            return asset_id
        elif len(asset_name) >= 13:
            raise exceptions.AssetNameError('long asset names must be numeric')

    if asset_name[0] == 'A':
        raise exceptions.AssetNameError(
            'non‐numeric asset name starts with ‘A’')

    # Convert the Base 26 string to an integer.
    n = 0
    for c in asset_name:
        n *= 26
        if c not in B26_DIGITS:
            raise exceptions.AssetNameError('invalid character:', c)
        digit = B26_DIGITS.index(c)
        n += digit
    asset_id = n

    if asset_id < 26**3:
        raise exceptions.AssetNameError('too short')

    return asset_id
Beispiel #3
0
def validate_subasset_parent_name(asset_name):
    if asset_name == config.BTC:
        raise exceptions.AssetNameError('parent asset cannot be {}'.format(config.BTC))
    if asset_name == config.XCP:
        raise exceptions.AssetNameError('parent asset cannot be {}'.format(config.XCP))
    if len(asset_name) < 4:
        raise exceptions.AssetNameError('parent asset name too short')
    if len(asset_name) >= 13:
        raise exceptions.AssetNameError('parent asset name too long')
    if asset_name[0] == 'A':
        raise exceptions.AssetNameError('parent asset name starts with ‘A’')
    for c in asset_name:
        if c not in B26_DIGITS:
            raise exceptions.AssetNameError('parent asset name contains invalid character:', c)
    return True
def unpack(db, message, block_index):
    try:
        # account for memo bytes
        memo_bytes_length = len(message) - LENGTH
        if memo_bytes_length < 0:
            raise exceptions.UnpackError('invalid message length')
        if memo_bytes_length > MAX_MEMO_LENGTH:
            raise exceptions.UnpackError('memo too long')

        struct_format = FORMAT + ('{}s'.format(memo_bytes_length))
        asset_id, quantity, short_address_bytes, memo_bytes = struct.unpack(
            struct_format, message)
        if len(memo_bytes) == 0:
            memo_bytes = None

        # unpack address
        full_address = address.unpack(short_address_bytes)

        # asset id to name
        asset = util.generate_asset_name(asset_id, block_index)
        if asset == config.BTC:
            raise exceptions.AssetNameError('{} not allowed'.format(
                config.BTC))

    except (struct.error) as e:
        logger.warning("enhanced send unpack error: {}".format(e))
        raise exceptions.UnpackError('could not unpack')

    except (exceptions.AssetNameError, exceptions.AssetIDError) as e:
        logger.warning("enhanced send invalid asset id: {}".format(e))
        raise exceptions.UnpackError('asset id invalid')

    unpacked = {
        'asset': asset,
        'quantity': quantity,
        'address': full_address,
        'memo': memo_bytes,
    }
    return unpacked