예제 #1
0
def close_dispute(resolution_json, db, message_listener, notification_listener, testnet):
    """
    This function processes a dispute close message received from the moderator. It will
    store the resolution in the contract and send a notification to the listeners telling
    them that the dispute is resolved.

    Args:
        resolution_json: The `dispute_resolution` portion of the contract received from the moderator.
        db: a `Database` object.
        message_listener: a `MessageListenerImpl` object.
        notification_listener: a `NotificationListenerImpl` object.
        testnet: `bool` of whether we're on testnet or not.
    """

    order_id = resolution_json["dispute_resolution"]["resolution"]["order_id"]

    if os.path.exists(DATA_FOLDER + "purchases/in progress/" + order_id + ".json"):
        file_path = DATA_FOLDER + "purchases/trade receipts/" + order_id + ".json"
    elif os.path.exists(DATA_FOLDER + "store/contracts/in progress/" + order_id + ".json"):
        file_path = DATA_FOLDER + "store/contracts/in progress/" + order_id + ".json"

    with open(file_path, 'r') as filename:
        contract = json.load(filename, object_pairs_hook=OrderedDict)

    for moderator in contract["vendor_offer"]["listing"]["moderators"]:
        if moderator["guid"] == contract["buyer_order"]["order"]["moderator"]:
            moderator_guid = unhexlify(moderator["guid"])
            moderator_handle = moderator["blockchain_id"]
            moderator_pubkey = unhexlify(moderator["pubkeys"]["signing"]["key"])
            moderator_enc_key = unhexlify(moderator["pubkeys"]["encryption"]["key"])
            moderator_avatar = unhexlify(moderator["avatar"])

    verify_key = nacl.signing.VerifyKey(moderator_pubkey)
    verify_key.verify(json.dumps(resolution_json["dispute_resolution"]["resolution"], indent=4),
                      resolution_json["dispute_resolution"]["signature"])

    contract["dispute_resolution"] = resolution_json["dispute_resolution"]

    with open(file_path, 'wb') as outfile:
        outfile.write(json.dumps(contract, indent=4))

    p = PlaintextMessage()
    p.sender_guid = moderator_guid
    p.handle = moderator_handle
    p.signed_pubkey = moderator_pubkey
    p.encryption_pubkey = moderator_enc_key
    p.subject = order_id
    p.type = PlaintextMessage.Type.Value("DISPUTE_CLOSE")
    p.message = resolution_json["dispute_resolution"]["resolution"]["decision"]
    p.timestamp = time.time()
    p.avatar_hash = moderator_avatar

    message_listener.notify(p, "")
    notification_listener.notify(moderator_guid, moderator_handle, "dispute_close", order_id,
                                 contract["vendor_offer"]["listing"]["item"]["title"],
                                 contract["vendor_offer"]["listing"]["item"]["image_hashes"][0])
예제 #2
0
def close_dispute(resolution_json, db, message_listener, notification_listener,
                  testnet):
    """
    This function processes a dispute close message received from the moderator. It will
    store the resolution in the contract and send a notification to the listeners telling
    them that the dispute is resolved.

    Args:
        resolution_json: The `dispute_resolution` portion of the contract received from the moderator.
        db: a `Database` object.
        message_listener: a `MessageListenerImpl` object.
        notification_listener: a `NotificationListenerImpl` object.
        testnet: `bool` of whether we're on testnet or not.
    """

    order_id = resolution_json["dispute_resolution"]["resolution"]["order_id"]

    if os.path.exists(DATA_FOLDER + "purchases/in progress/" + order_id +
                      ".json"):
        file_path = DATA_FOLDER + "purchases/trade receipts/" + order_id + ".json"
    elif os.path.exists(DATA_FOLDER + "store/contracts/in progress/" +
                        order_id + ".json"):
        file_path = DATA_FOLDER + "store/contracts/in progress/" + order_id + ".json"

    with open(file_path, 'r') as filename:
        contract = json.load(filename, object_pairs_hook=OrderedDict)

    for moderator in contract["vendor_offer"]["listing"]["moderators"]:
        if moderator["guid"] == contract["buyer_order"]["order"]["moderator"]:
            moderator_guid = unhexlify(moderator["guid"])
            moderator_handle = moderator["blockchain_id"]
            moderator_pubkey = unhexlify(
                moderator["pubkeys"]["signing"]["key"])
            moderator_enc_key = unhexlify(
                moderator["pubkeys"]["encryption"]["key"])
            moderator_avatar = unhexlify(moderator["avatar"])

    verify_key = nacl.signing.VerifyKey(moderator_pubkey)
    verify_key.verify(
        json.dumps(resolution_json["dispute_resolution"]["resolution"],
                   indent=4),
        resolution_json["dispute_resolution"]["signature"])

    contract["dispute_resolution"] = resolution_json["dispute_resolution"]

    with open(file_path, 'wb') as outfile:
        outfile.write(json.dumps(contract, indent=4))

    p = PlaintextMessage()
    p.sender_guid = moderator_guid
    p.handle = moderator_handle
    p.signed_pubkey = moderator_pubkey
    p.encryption_pubkey = moderator_enc_key
    p.subject = order_id
    p.type = PlaintextMessage.Type.Value("DISPUTE_CLOSE")
    p.message = resolution_json["dispute_resolution"]["resolution"]["decision"]
    p.timestamp = time.time()
    p.avatar_hash = moderator_avatar

    message_listener.notify(p, "")
    notification_listener.notify(
        moderator_guid, moderator_handle, "dispute_close", order_id,
        contract["vendor_offer"]["listing"]["item"]["title"],
        contract["vendor_offer"]["listing"]["item"]["image_hashes"][0])
예제 #3
0
def process_dispute(contract, db, message_listener, notification_listener,
                    testnet):
    """
    This function processes a dispute message received from another node. It checks the
    contract to see if this a dispute for a purchase we made, a dispute for one of our
    sales, or a new case if we are the moderator.

    If it's a purchase or sale it will
    update the order status to disputed and push a notification to the listener.

    If it's a new case it will validate the contract, create a new case in the db,
    and push a notification to the listener.

    Args:
        contract: a json contract of the current order state. Should have a "dispute"
            object attached with dispute info.
        db: a `Database` object.
        message_listener: a `MessageListenerImpl` object.
        notification_listener: a `NotificationListenerImpl` object.
        testnet: `bool` of whether we're on testnet or not.
    """
    tmp_contract = contract
    if "vendor_order_confirmation" in tmp_contract:
        del tmp_contract["vendor_order_confirmation"]
    if "buyer_receipt" in tmp_contract:
        del tmp_contract["buyer_receipt"]

    order_id = digest(json.dumps(tmp_contract, indent=4)).encode("hex")
    own_guid = KeyChain(db).guid.encode("hex")

    if contract["dispute"]["info"]["guid"] == contract["vendor_offer"][
            "listing"]["id"]["guid"]:
        guid = unhexlify(contract["vendor_offer"]["listing"]["id"]["guid"])
        signing_key = unhexlify(
            contract["vendor_offer"]["listing"]["id"]["pubkeys"]["guid"])
        if "blockchain_id" in contract["vendor_offer"]["listing"]["id"]:
            handle = contract["vendor_offer"]["listing"]["id"]["blockchain_id"]
        else:
            handle = ""
        encryption_key = unhexlify(
            contract["vendor_offer"]["listing"]["id"]["pubkeys"]["encryption"])
        proof_sig = contract["dispute"]["info"]["proof_sig"]
    elif contract["dispute"]["info"]["guid"] == contract["buyer_order"][
            "order"]["id"]["guid"]:
        guid = unhexlify(contract["buyer_order"]["order"]["id"]["guid"])
        signing_key = unhexlify(
            contract["buyer_order"]["order"]["id"]["pubkeys"]["guid"])
        if "blockchain_id" in contract["buyer_order"]["order"]["id"]:
            handle = contract["buyer_order"]["order"]["id"]["blockchain_id"]
        else:
            handle = ""
        encryption_key = unhexlify(
            contract["buyer_order"]["order"]["id"]["pubkeys"]["encryption"])
        proof_sig = None
    else:
        raise Exception("Dispute guid not in contract")

    verify_key = nacl.signing.VerifyKey(signing_key)
    verify_key.verify(json.dumps(contract["dispute"]["info"], indent=4),
                      contract["dispute"]["signature"])

    p = PlaintextMessage()
    p.sender_guid = guid
    p.handle = handle
    p.signed_pubkey = signing_key
    p.encryption_pubkey = encryption_key
    p.subject = order_id
    p.type = PlaintextMessage.Type.Value("DISPUTE_OPEN")
    p.message = contract["dispute"]["info"]["claim"]
    p.timestamp = time.time()
    p.avatar_hash = contract["dispute"]["info"]["avatar_hash"]

    if db.Purchases().get_purchase(order_id) is not None:
        db.Purchases().update_status(order_id, 4)

    elif db.Sales().get_sale(order_id) is not None:
        db.Purchases().update_status(order_id, 4)

    elif "moderators" in contract["vendor_offer"]["listing"]:
        # TODO: make sure a case isn't already open in the db
        is_selected = False
        for moderator in contract["vendor_offer"]["listing"]["moderators"]:
            if moderator["guid"] == own_guid and contract["buyer_order"][
                    "order"]["moderator"] == own_guid:
                is_selected = True
        if not is_selected:
            raise Exception("Not a moderator for this contract")
        else:
            if "blockchain_id" in contract["vendor_offer"]["listing"]["id"]:
                vendor = contract["vendor_offer"]["listing"]["id"][
                    "blockchain_id"]
            else:
                vendor = contract["vendor_offer"]["listing"]["id"]["guid"]
            if "blockchain_id" in contract["buyer_order"]["order"]["id"]:
                buyer = contract["buyer_order"]["order"]["id"]["blockchain_id"]
            else:
                buyer = contract["buyer_order"]["order"]["id"]["guid"]

            c = Contract(db, contract=contract, testnet=testnet)

            validation_failures = c.validate_for_moderation(proof_sig)

            db.Cases().new_case(
                order_id, contract["vendor_offer"]["listing"]["item"]["title"],
                time.time(), contract["buyer_order"]["order"]["date"],
                contract["buyer_order"]["order"],
                float(contract["buyer_order"]["order"]["payment"]["amount"]),
                contract["vendor_offer"]["listing"]["item"]["image_hashes"][0],
                buyer, vendor, json.dumps(validation_failures),
                contract["dispute"]["info"]["claim"])

            with open(DATA_FOLDER + "cases/" + order_id + ".json",
                      'wb') as outfile:
                outfile.write(json.dumps(contract, indent=4))
    else:
        raise Exception("Order ID for dispute not found")

    message_listener.notify(p, "")
    notification_listener.notify(
        guid, handle, "dispute_open", order_id,
        contract["vendor_offer"]["listing"]["item"]["title"],
        contract["vendor_offer"]["listing"]["item"]["image_hashes"][0])
예제 #4
0
def process_dispute(contract, db, message_listener, notification_listener, testnet):
    """
    This function processes a dispute message received from another node. It checks the
    contract to see if this a dispute for a purchase we made, a dispute for one of our
    sales, or a new case if we are the moderator.

    If it's a purchase or sale it will
    update the order status to disputed and push a notification to the listener.

    If it's a new case it will validate the contract, create a new case in the db,
    and push a notification to the listener.

    Args:
        contract: a json contract of the current order state. Should have a "dispute"
            object attached with dispute info.
        db: a `Database` object.
        message_listener: a `MessageListenerImpl` object.
        notification_listener: a `NotificationListenerImpl` object.
        testnet: `bool` of whether we're on testnet or not.
    """
    tmp_contract = contract
    if "vendor_order_confirmation" in tmp_contract:
        del tmp_contract["vendor_order_confirmation"]
    if "buyer_receipt" in tmp_contract:
        del tmp_contract["buyer_receipt"]

    order_id = digest(json.dumps(tmp_contract, indent=4)).encode("hex")
    own_guid = KeyChain(db).guid.encode("hex")

    if contract["dispute"]["info"]["guid"] == contract["vendor_offer"]["listing"]["id"]["guid"]:
        guid = unhexlify(contract["vendor_offer"]["listing"]["id"]["guid"])
        signing_key = unhexlify(contract["vendor_offer"]["listing"]["id"]["pubkeys"]["guid"])
        if "blockchain_id" in contract["vendor_offer"]["listing"]["id"]:
            handle = contract["vendor_offer"]["listing"]["id"]["blockchain_id"]
        else:
            handle = ""
        encryption_key = unhexlify(contract["vendor_offer"]["listing"]["id"]["pubkeys"]["encryption"])
        proof_sig = contract["dispute"]["info"]["proof_sig"]
    elif contract["dispute"]["info"]["guid"] == contract["buyer_order"]["order"]["id"]["guid"]:
        guid = unhexlify(contract["buyer_order"]["order"]["id"]["guid"])
        signing_key = unhexlify(contract["buyer_order"]["order"]["id"]["pubkeys"]["guid"])
        if "blockchain_id" in contract["buyer_order"]["order"]["id"]:
            handle = contract["buyer_order"]["order"]["id"]["blockchain_id"]
        else:
            handle = ""
        encryption_key = unhexlify(contract["buyer_order"]["order"]["id"]["pubkeys"]["encryption"])
        proof_sig = None
    else:
        raise Exception("Dispute guid not in contract")

    verify_key = nacl.signing.VerifyKey(signing_key)
    verify_key.verify(json.dumps(contract["dispute"]["info"], indent=4),
                      contract["dispute"]["signature"])

    p = PlaintextMessage()
    p.sender_guid = guid
    p.handle = handle
    p.signed_pubkey = signing_key
    p.encryption_pubkey = encryption_key
    p.subject = order_id
    p.type = PlaintextMessage.Type.Value("DISPUTE_OPEN")
    p.message = contract["dispute"]["info"]["claim"]
    p.timestamp = time.time()
    p.avatar_hash = contract["dispute"]["info"]["avatar_hash"]

    if db.Purchases().get_purchase(order_id) is not None:
        db.Purchases().update_status(order_id, 4)

    elif db.Sales().get_sale(order_id) is not None:
        db.Purchases().update_status(order_id, 4)

    elif "moderators" in contract["vendor_offer"]["listing"]:
        # TODO: make sure a case isn't already open in the db
        is_selected = False
        for moderator in contract["vendor_offer"]["listing"]["moderators"]:
            if moderator["guid"] == own_guid and contract["buyer_order"]["order"]["moderator"] == own_guid:
                is_selected = True
        if not is_selected:
            raise Exception("Not a moderator for this contract")
        else:
            if "blockchain_id" in contract["vendor_offer"]["listing"]["id"]:
                vendor = contract["vendor_offer"]["listing"]["id"]["blockchain_id"]
            else:
                vendor = contract["vendor_offer"]["listing"]["id"]["guid"]
            if "blockchain_id" in contract["buyer_order"]["order"]["id"]:
                buyer = contract["buyer_order"]["order"]["id"]["blockchain_id"]
            else:
                buyer = contract["buyer_order"]["order"]["id"]["guid"]

            c = Contract(db, contract=contract, testnet=testnet)

            validation_failures = c.validate_for_moderation(proof_sig)

            db.Cases().new_case(order_id,
                                contract["vendor_offer"]["listing"]["item"]["title"],
                                time.time(),
                                contract["buyer_order"]["order"]["date"],
                                contract["buyer_order"]["order"],
                                float(contract["buyer_order"]["order"]["payment"]["amount"]),
                                contract["vendor_offer"]["listing"]["item"]["image_hashes"][0],
                                buyer, vendor, json.dumps(validation_failures),
                                contract["dispute"]["info"]["claim"])

            with open(DATA_FOLDER + "cases/" + order_id + ".json", 'wb') as outfile:
                outfile.write(json.dumps(contract, indent=4))
    else:
        raise Exception("Order ID for dispute not found")

    message_listener.notify(p, "")
    notification_listener.notify(guid, handle, "dispute_open", order_id,
                                 contract["vendor_offer"]["listing"]["item"]["title"],
                                 contract["vendor_offer"]["listing"]["item"]["image_hashes"][0])