Ejemplo n.º 1
0
def get_mutable_data_route_hash(route):
    """
   Given an unserialized route, get its hash.
   Return the hash on success
   Return None on error
   """
    route_json = json_stable_serialize(route)
    if route_json is None:
        return None

    return get_data_hash(route_json)
Ejemplo n.º 2
0
def get_mutable_data_route_hash( route ):
   """
   Given an unserialized route, get its hash.
   Return the hash on success
   Return None on error
   """
   route_json = json_stable_serialize( route )
   if route_json is None:
      return None

   return get_data_hash( route_json )
Ejemplo n.º 3
0
def put_mutable_data(data, privatekey):
    """
   Given the unserialized data, store it into our mutable data stores.
   Do so in a best-effor way.  This method only fails if all storage providers fail.

   If the data is not signed, then it will be signed with the given private key.

   Return True on success
   Return False on error
   """

    data_id = data['id']
    data_text = data['data']
    ver = data['ver']
    sig = data.get('sig', None)

    if sig is None:
        sig = sign_mutable_data(data, privatekey)
        data['sig'] = sig

    data_json = json_stable_serialize(data)

    successes = 0

    for handler in storage_handlers:

        if not hasattr(handler, "put_mutable_handler"):
            continue

        rc = False

        try:

            rc = handler.put_mutable_handler(data_id, ver, sig, data_json)
        except Exception, e:

            log.exception(e)
            continue

        if not rc:
            log.error("Failed to replicate with '%s'" % handler.__name__)

        else:
            successes += 1
Ejemplo n.º 4
0
def put_mutable_data( data, privatekey ):
   """
   Given the unserialized data, store it into our mutable data stores.
   Do so in a best-effor way.  This method only fails if all storage providers fail.

   If the data is not signed, then it will be signed with the given private key.

   Return True on success
   Return False on error
   """

   data_id = data['id']
   data_text = data['data']
   ver = data['ver']
   sig = data.get('sig', None)

   if sig is None:
      sig = sign_mutable_data( data, privatekey )
      data['sig'] = sig

   data_json = json_stable_serialize( data )

   successes = 0

   for handler in storage_handlers:

      if not hasattr( handler, "put_mutable_handler" ):
         continue

      rc = False

      try:

         rc = handler.put_mutable_handler( data_id, ver, sig, data_json )
      except Exception, e:

         log.exception( e )
         continue

      if not rc:
         log.error("Failed to replicate with '%s'" % handler.__name__)

      else:
         successes += 1
Ejemplo n.º 5
0
        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]

        rd = get_immutable_handler(hash_data(d))
Ejemplo n.º 6
0
        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]

        rd = get_immutable_handler(hash_data(d))
Ejemplo n.º 7
0
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
Ejemplo n.º 8
0
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