Example #1
0
def unpack(db, message):
    try:
        asset_id, quantity, tag = struct.unpack(FORMAT, message)
        asset = util.get_asset_name(db, asset_id, util.CURRENT_BLOCK_INDEX)

    except struct.error:
        raise UnpackError('could not unpack')

    except util.AssetNameError:
        raise UnpackError('asset id invalid')

    return asset, quantity, tag
Example #2
0
def unpack(db, message, block_index):
    try:
        asset_id, quantity = struct.unpack(FORMAT, message)
        asset = util.get_asset_name(db, asset_id, block_index)

    except struct.error:
        raise UnpackError('could not unpack')

    except AssetNameError:
        raise UnpackError('asset id invalid')

    unpacked = {
                'asset': asset,
                'quantity': quantity
               }
    return unpacked
Example #3
0
def parse(db, tx, message):
    order_parse_cursor = db.cursor()

    # Unpack message.
    try:
        if len(message) != LENGTH:
            raise exceptions.UnpackError
        give_id, give_quantity, get_id, get_quantity, expiration, fee_required = struct.unpack(FORMAT, message)
        give_asset = util.get_asset_name(db, give_id, tx["block_index"])
        get_asset = util.get_asset_name(db, get_id, tx["block_index"])
        status = "open"
    except (exceptions.UnpackError, exceptions.AssetNameError, struct.error) as e:
        give_asset, give_quantity, get_asset, get_quantity, expiration, fee_required = 0, 0, 0, 0, 0, 0
        status = "invalid: could not unpack"

    price = 0
    if status == "open":
        try:
            price = util.price(get_quantity, give_quantity)
        except ZeroDivisionError:
            price = 0

        # Overorder
        order_parse_cursor.execute(
            """SELECT * FROM balances \
                                      WHERE (address = ? AND asset = ?)""",
            (tx["source"], give_asset),
        )
        balances = list(order_parse_cursor)
        if give_asset != config.SCH:
            if not balances:
                give_quantity = 0
            else:
                balance = balances[0]["quantity"]
                if balance < give_quantity:
                    give_quantity = balance
                    get_quantity = int(price * give_quantity)

        problems = validate(
            db,
            tx["source"],
            give_asset,
            give_quantity,
            get_asset,
            get_quantity,
            expiration,
            fee_required,
            tx["block_index"],
        )
        if problems:
            status = "invalid: " + "; ".join(problems)

    # Debit give quantity. (Escrow.)
    if status == "open":
        if give_asset != config.SCH:  # No need (or way) to debit SCH.
            util.debit(db, tx["source"], give_asset, give_quantity, action="open order", event=tx["tx_hash"])

    # Add parsed transaction to message-type–specific table.
    bindings = {
        "tx_index": tx["tx_index"],
        "tx_hash": tx["tx_hash"],
        "block_index": tx["block_index"],
        "source": tx["source"],
        "give_asset": give_asset,
        "give_quantity": give_quantity,
        "give_remaining": give_quantity,
        "get_asset": get_asset,
        "get_quantity": get_quantity,
        "get_remaining": get_quantity,
        "expiration": expiration,
        "expire_index": tx["block_index"] + expiration,
        "fee_required": fee_required,
        "fee_required_remaining": fee_required,
        "fee_provided": tx["fee"],
        "fee_provided_remaining": tx["fee"],
        "status": status,
    }
    sql = "insert into orders values(:tx_index, :tx_hash, :block_index, :source, :give_asset, :give_quantity, :give_remaining, :get_asset, :get_quantity, :get_remaining, :expiration, :expire_index, :fee_required, :fee_required_remaining, :fee_provided, :fee_provided_remaining, :status)"
    order_parse_cursor.execute(sql, bindings)

    # Match.
    if status == "open" and tx["block_index"] != config.MEMPOOL_BLOCK_INDEX:
        match(db, tx)

    order_parse_cursor.close()