d_id, d, n, s, url = test_data[i]

        rc = put_immutable_handler(hash_data(d), d, "unused")
        if not rc:
            raise Exception("put_immutable_handler('%s') failed" % d)

    # put_mutable_handler
    print "put_mutable_handler"
    for i in xrange(0, len(test_data)):

        d_id, d, n, s, url = test_data[i]

        data_url = make_mutable_url(d_id)

        data = mutable_data(d_id, d, n, sig=s)

        data_json = json_stable_serialize(data)

        rc = put_mutable_handler(d_id, n, "unused", data_json)
        if not rc:
            raise Exception("put_mutable_handler('%s', '%s') failed" %
                            (d_id, d))

        test_data[i][4] = data_url

    # get_immutable_handler
    print "get_immutable_handler"
    for i in xrange(0, len(test_data)):

        d_id, d, n, s, url = test_data[i]
def put_mutable(name, data_id, data_text, privatekey, proxy=None, create=True,
                txid=None, ver=None, make_ver=None, conf=None ):
    """
    put_mutable

    ** Consistency **

    ver, if given, is the version to include in the data.
    make_ver, if given, is a callback that takes the data_id, data_text, and current version as arguments, and generates the version to be included in the data record uploaded.
    If ver is not given, but make_ver is, then make_ver will be used to generate the version.
    If neither ver nor make_ver are given, the mutable data (if it already exists) is fetched, and the version is calculated as the larget known version + 1.

    ** Durability **

    Replication is best-effort.  If one storage provider driver succeeds, the put_mutable succeeds.  If they all fail, then put_mutable fails.
    More complex behavior can be had by creating a "meta-driver" that calls existing drivers' methods in the desired manner.
    """

    if proxy is None:
        proxy = get_default_proxy()

    result = {}
    user = get_name_record(name, create_if_absent=create)
    if 'error' in user:

        return {'error': "Unable to load user record: %s" % user['error']}

    route = None
    exists = user_db.has_mutable_data_route(user, data_id)
    old_hash = None
    cur_hash = None
    new_ver = ver

    if ver is None:

        if exists:
            # mutable record already exists.
            # generate one automatically.
            # use the existing locally-stored version,
            # and fall back to using the last-known version
            # from the existing mutable data record.
            new_ver = load_mutable_data_version( config.get_config(), name, data_id, try_remote=True )
            if new_ver is None:
                # data exists, but we couldn't figure out the version
                return {'error': "Unable to determine version"}

        if make_ver is not None:
            # generate version
            new_ver = make_ver( data_id, data_text, new_ver )

        else:
            # no version known, and no way to generate it.
            # by default, start at 1.  we'll manage it ourselves.
            if new_ver is None:
                new_ver = 1
            else:
                new_ver += 1


    # do we have a route for this data yet?
    if not exists:

        if not create:
            # won't create; expect it to exist
            return {'error': 'No such route'}

        # need to put one
        urls = storage.make_mutable_urls(data_id)
        if len(urls) == 0:
            return {"error": "No routes constructed"}

        writer_pubkey = pybitcointools.privkey_to_pubkey(privatekey)

        route = storage.mutable_data_route(data_id, urls,
                                           writer_pubkey=writer_pubkey)

        user_db.add_mutable_data_route(user, route)

        user_json = user_db.serialize_user(user)

        # update the user record with the new route
        update_result = update(name, user_json, privatekey, txid=txid, proxy=proxy)
        if 'error' in update_result:

            # update failed; caller should try again
            return update_result

        txid = update_result['transaction_hash']
        cur_hash = update_result['value_hash']

    else:

        route = user_db.get_mutable_data_route(user, data_id)
        if route is None:

            return {"error": "No such route"}

    # generate the data
    data = storage.mutable_data(data_id, data_text, new_ver, privkey=privatekey)
    if data is None:
        return {"error": "Failed to generate data record"}

    # serialize...
    data_json = parsing.json_stable_serialize(data)

    # replicate...
    store_rc = storage.put_mutable_data( data, privatekey )
    if not store_rc:
        result['error'] = "Failed to store mutable data"

    else:
        result['status'] = True

    result['transaction_hash'] = txid

    if cur_hash:
        # propagate
        result['value_hash'] = cur_hash

    # cache new version
    store_mutable_data_version( conf, data_id, new_ver )

    return result
Beispiel #3
0
        d_id, d, n, s, url = test_data[i]

        rc = put_immutable_handler(hash_data(d), d, "unused")
        if not rc:
            raise Exception("put_immutable_handler('%s') failed" % d)

    # put_mutable_handler
    print "put_mutable_handler"
    for i in xrange(0, len(test_data)):

        d_id, d, n, s, url = test_data[i]

        data_url = make_mutable_url(d_id)

        data = mutable_data(d_id, d, n, sig=s)

        data_json = json_stable_serialize(data)

        rc = put_mutable_handler(d_id, n, "unused", data_json)

        if not rc:
            raise Exception("put_mutable_handler('%s', '%s') failed" % (d_id, d))

        test_data[i][4] = data_url

    # get_immutable_handler
    print "get_immutable_handler"
    for i in xrange(0, len(test_data)):

        d_id, d, n, s, url = test_data[i]
def put_mutable(name,
                data_id,
                data_text,
                privatekey,
                proxy=None,
                create=True,
                txid=None,
                ver=None,
                make_ver=None,
                conf=None):
    """
    put_mutable

    ** Consistency **

    ver, if given, is the version to include in the data.
    make_ver, if given, is a callback that takes the data_id, data_text, and current version as arguments, and generates the version to be included in the data record uploaded.
    If ver is not given, but make_ver is, then make_ver will be used to generate the version.
    If neither ver nor make_ver are given, the mutable data (if it already exists) is fetched, and the version is calculated as the larget known version + 1.

    ** Durability **

    Replication is best-effort.  If one storage provider driver succeeds, the put_mutable succeeds.  If they all fail, then put_mutable fails.
    More complex behavior can be had by creating a "meta-driver" that calls existing drivers' methods in the desired manner.
    """

    if proxy is None:
        proxy = get_default_proxy()

    result = {}
    user = get_name_record(name, create_if_absent=create)
    if 'error' in user:

        return {'error': "Unable to load user record: %s" % user['error']}

    route = None
    exists = user_db.has_mutable_data_route(user, data_id)
    old_hash = None
    cur_hash = None
    new_ver = ver

    if ver is None:

        if exists:
            # mutable record already exists.
            # generate one automatically.
            # use the existing locally-stored version,
            # and fall back to using the last-known version
            # from the existing mutable data record.
            new_ver = load_mutable_data_version(config.get_config(),
                                                name,
                                                data_id,
                                                try_remote=True)
            if new_ver is None:
                # data exists, but we couldn't figure out the version
                return {'error': "Unable to determine version"}

        if make_ver is not None:
            # generate version
            new_ver = make_ver(data_id, data_text, new_ver)

        else:
            # no version known, and no way to generate it.
            # by default, start at 1.  we'll manage it ourselves.
            if new_ver is None:
                new_ver = 1
            else:
                new_ver += 1

    # do we have a route for this data yet?
    if not exists:

        if not create:
            # won't create; expect it to exist
            return {'error': 'No such route'}

        # need to put one
        urls = storage.make_mutable_urls(data_id)
        if len(urls) == 0:
            return {"error": "No routes constructed"}

        writer_pubkey = pybitcointools.privkey_to_pubkey(privatekey)

        route = storage.mutable_data_route(data_id,
                                           urls,
                                           writer_pubkey=writer_pubkey)

        user_db.add_mutable_data_route(user, route)

        user_json = user_db.serialize_user(user)

        # update the user record with the new route
        update_result = update(name,
                               user_json,
                               privatekey,
                               txid=txid,
                               proxy=proxy)
        if 'error' in update_result:

            # update failed; caller should try again
            return update_result

        txid = update_result['transaction_hash']
        cur_hash = update_result['value_hash']

    else:

        route = user_db.get_mutable_data_route(user, data_id)
        if route is None:

            return {"error": "No such route"}

    # generate the data
    data = storage.mutable_data(data_id,
                                data_text,
                                new_ver,
                                privkey=privatekey)
    if data is None:
        return {"error": "Failed to generate data record"}

    # serialize...
    data_json = parsing.json_stable_serialize(data)

    # replicate...
    store_rc = storage.put_mutable_data(data, privatekey)
    if not store_rc:
        result['error'] = "Failed to store mutable data"

    else:
        result['status'] = True

    result['transaction_hash'] = txid

    if cur_hash:
        # propagate
        result['value_hash'] = cur_hash

    # cache new version
    store_mutable_data_version(conf, data_id, new_ver)

    return result