def record_exchange_result(db, exchange_id, status, error, participant):
    with db.get_cursor() as cursor:
        amount, fee, username, route = cursor.one("""
            UPDATE exchanges e
               SET status=%(status)s
                 , note=%(error)s
             WHERE id=%(exchange_id)s
               AND status <> %(status)s
         RETURNING amount, fee, participant
                 , ( SELECT r.*::exchange_routes
                       FROM exchange_routes r
                      WHERE r.id = e.route
                   ) AS route
        """, locals())
        assert participant.username == username
        assert isinstance(route, ExchangeRoute)
        route.set_attributes(participant=participant)  # XXX Red hot hack!

        if amount < 0:
            amount -= fee
            amount = amount if status == 'failed' else 0
            propagate_exchange(cursor, participant, route, error, -amount)
        else:
            amount = amount if status == 'succeeded' else 0
            propagate_exchange(cursor, participant, route, error, amount)
Updates the status of an exchange.
dataset/ETHPy150Open gratipay/gratipay.com/gratipay/billing/exchanges.py/record_exchange_result