Merge pull request #111 from lbryio/update-claim

claim updates
This commit is contained in:
Jack Robison 2016-08-09 03:29:12 -04:00 committed by GitHub
commit 0910711aca
7 changed files with 305 additions and 104 deletions

View file

@ -87,6 +87,10 @@ class LBRYFeeValidator(dict):
class Metadata(dict): class Metadata(dict):
@classmethod
def load_from_hex(cls, metadata):
return cls(json.loads(metadata.decode('hex')))
def __init__(self, metadata): def __init__(self, metadata):
dict.__init__(self) dict.__init__(self)
self.meta_version = None self.meta_version = None
@ -123,3 +127,9 @@ class Metadata(dict):
assert self.meta_version == self['ver'], "version mismatch" assert self.meta_version == self['ver'], "version mismatch"
break break
assert metadata == {}, "Unknown metadata keys: %s" % json.dumps(metadata.keys()) assert metadata == {}, "Unknown metadata keys: %s" % json.dumps(metadata.keys())
def serialize(self):
return json.dumps(self).encode("hex")
def as_json(self):
return json.dumps(self)

View file

@ -86,6 +86,7 @@ class LBRYWallet(object):
return True return True
d = self._open_db() d = self._open_db()
d.addCallback(lambda _: self._clean_bad_records())
d.addCallback(lambda _: self._start()) d.addCallback(lambda _: self._start())
d.addCallback(lambda _: start_manage()) d.addCallback(lambda _: start_manage())
return d return d
@ -320,6 +321,10 @@ class LBRYWallet(object):
for k in ['value', 'txid', 'n', 'height', 'amount']: for k in ['value', 'txid', 'n', 'height', 'amount']:
assert k in r, "getvalueforname response missing field %s" % k assert k in r, "getvalueforname response missing field %s" % k
def _log_success(claim_id):
log.info("lbry://%s complies with %s, claimid: %s", name, metadata.meta_version, claim_id)
return defer.succeed(None)
if 'error' in result: if 'error' in result:
log.warning("Got an error looking up a name: %s", result['error']) log.warning("Got an error looking up a name: %s", result['error'])
return Failure(UnknownNameError(name)) return Failure(UnknownNameError(name))
@ -331,55 +336,116 @@ class LBRYWallet(object):
except (ValueError, TypeError): except (ValueError, TypeError):
return Failure(InvalidStreamInfoError(name)) return Failure(InvalidStreamInfoError(name))
d = self._save_name_metadata(name, str(result['txid']), metadata['sources']['lbry_sd_hash']) txid = result['txid']
d.addCallback(lambda _: log.info("lbry://%s complies with %s" % (name, metadata.meta_version))) sd_hash = metadata['sources']['lbry_sd_hash']
d = self._save_name_metadata(name, txid, sd_hash)
d.addCallback(lambda _: self.get_claimid(name, txid))
d.addCallback(lambda cid: _log_success(cid))
d.addCallback(lambda _: metadata) d.addCallback(lambda _: metadata)
return d return d
def _get_claim_info(self, result, name): def get_claim(self, name, claim_id):
def _check_result_fields(r): d = self.get_claims_for_name(name)
for k in ['value', 'txid', 'n', 'height', 'amount']: d.addCallback(lambda claims: next(claim for claim in claims['claims'] if claim['claimId'] == claim_id))
assert k in r, "getvalueforname response missing field %s" % k
def _build_response(m, result):
result['value'] = m
return result
if 'error' in result:
log.warning("Got an error looking up a name: %s", result['error'])
return Failure(UnknownNameError(name))
_check_result_fields(result)
try:
metadata = Metadata(json.loads(result['value']))
except (ValueError, TypeError):
return Failure(InvalidStreamInfoError(name))
d = self._save_name_metadata(name, str(result['txid']), metadata['sources']['lbry_sd_hash'])
d.addCallback(lambda _: log.info("lbry://%s complies with %s" % (name, metadata.meta_version)))
d.addCallback(lambda _: _build_response(metadata, result))
return d return d
def get_claim_info(self, name): def get_claimid(self, name, txid):
d = self._get_value_for_name(name) def _get_id_for_return(claim_id):
d.addCallback(lambda r: self._get_claim_info(r, name)) if claim_id:
return defer.succeed(claim_id)
else:
d = self.get_claims_from_tx(txid)
d.addCallback(lambda claims: next(c['claimId'] for c in claims if c['name'] == name))
d.addCallback(lambda cid: self._update_claimid(cid, name, txid))
return d
d = self._get_claimid_for_tx(name, txid)
d.addCallback(_get_id_for_return)
return d return d
def get_claim_info(self, name, txid=None):
if not txid:
d = self._get_value_for_name(name)
d.addCallback(lambda r: self._get_claim_info(name, r['txid']))
else:
d = self._get_claim_info(name, txid)
d.addErrback(lambda _: False)
return d
def _get_claim_info(self, name, txid):
def _build_response(claim):
result = {}
try:
metadata = Metadata(json.loads(claim['value']))
meta_ver = metadata.meta_version
sd_hash = metadata['sources']['lbry_sd_hash']
d = self._save_name_metadata(name, txid, sd_hash)
except AssertionError:
metadata = claim['value']
meta_ver = "Non-compliant"
d = defer.succeed(None)
claim_id = claim['claimId']
result['claim_id'] = claim_id
result['amount'] = claim['nEffectiveAmount']
result['height'] = claim['nHeight']
result['name'] = name
result['txid'] = txid
result['value'] = metadata
result['supports'] = [{'txid': support['txid'], 'n': support['n']} for support in claim['supports']]
result['meta_version'] = meta_ver
log.info("get claim info lbry://%s metadata: %s, claimid: %s", name, meta_ver, claim_id)
d.addCallback(lambda _: self.get_name_claims())
d.addCallback(lambda r: [c['txid'] for c in r])
d.addCallback(lambda my_claims: _add_is_mine(result, my_claims))
return d
def _add_is_mine(response, my_txs):
response['is_mine'] = response['txid'] in my_txs
return response
d = self.get_claimid(name, txid)
d.addCallback(lambda claim_id: self.get_claim(name, claim_id))
d.addCallback(_build_response)
return d
def get_claims_for_name(self, name):
d = self._get_claims_for_name(name)
return d
def update_metadata(self, new_metadata, old_metadata):
meta_for_return = old_metadata if isinstance(old_metadata, dict) else {}
for k in new_metadata:
meta_for_return[k] = new_metadata[k]
return defer.succeed(Metadata(meta_for_return))
def claim_name(self, name, bid, m): def claim_name(self, name, bid, m):
def _save_metadata(txid, metadata):
metadata = Metadata(m)
d = self._send_name_claim(name, json.dumps(metadata), bid)
def _save_metadata(txid):
log.info("Saving metadata for claim %s" % txid) log.info("Saving metadata for claim %s" % txid)
d = self._save_name_metadata(name, txid, metadata['sources']['lbry_sd_hash']) d = self._save_name_metadata(name, txid, metadata['sources']['lbry_sd_hash'])
d.addCallback(lambda _: txid) d.addCallback(lambda _: txid)
return d return d
d.addCallback(_save_metadata) def _claim_or_update(claim, metadata, _bid):
if not claim:
log.info("No claim yet, making a new one")
return self._send_name_claim(name, metadata.as_json(), _bid)
if not claim['is_mine']:
log.info("Making a contesting claim")
return self._send_name_claim(name, metadata.as_json(), _bid)
else:
log.info("Updating over own claim")
d = self.update_metadata(metadata, claim['value'])
d.addCallback(lambda new_metadata: self._send_name_claim_update(name, claim['claim_id'], claim['txid'], new_metadata, _bid))
return d
meta = Metadata(m)
d = self.get_claim_info(name)
d.addCallback(lambda claim: _claim_or_update(claim, meta, bid))
d.addCallback(lambda txid: _save_metadata(txid, meta))
return d return d
def abandon_name(self, txid): def abandon_name(self, txid):
@ -415,19 +481,14 @@ class LBRYWallet(object):
dl.addCallback(abandon) dl.addCallback(abandon)
return dl return dl
def support_claim(self, name, claim_id, amount):
return self._support_claim(name, claim_id, amount)
def get_tx(self, txid): def get_tx(self, txid):
d = self._get_raw_tx(txid) d = self._get_raw_tx(txid)
d.addCallback(self._get_decoded_tx) d.addCallback(self._get_decoded_tx)
return d return d
def update_name(self, name, bid, value, old_txid):
d = self._get_value_for_name(name)
d.addCallback(lambda r: self.abandon_name(r['txid'] if not old_txid else old_txid))
d.addCallback(lambda r: log.info("Abandon claim tx %s" % str(r)))
d.addCallback(lambda _: self.claim_name(name, bid, value))
return d
def get_name_and_validity_for_sd_hash(self, sd_hash): def get_name_and_validity_for_sd_hash(self, sd_hash):
d = self._get_claim_metadata_for_sd_hash(sd_hash) d = self._get_claim_metadata_for_sd_hash(sd_hash)
d.addCallback(lambda name_txid: self._get_status_of_claim(name_txid[1], name_txid[0], sd_hash) if name_txid is not None else None) d.addCallback(lambda name_txid: self._get_status_of_claim(name_txid[1], name_txid[0], sd_hash) if name_txid is not None else None)
@ -530,21 +591,45 @@ class LBRYWallet(object):
def _open_db(self): def _open_db(self):
self.db = adbapi.ConnectionPool('sqlite3', os.path.join(self.db_dir, "blockchainname.db"), self.db = adbapi.ConnectionPool('sqlite3', os.path.join(self.db_dir, "blockchainname.db"),
check_same_thread=False) check_same_thread=False)
return self.db.runQuery("create table if not exists name_metadata (" +
def create_tables(transaction):
transaction.execute("create table if not exists name_metadata (" +
" name text, " + " name text, " +
" txid text, " + " txid text, " +
" sd_hash text)") " sd_hash text)")
transaction.execute("create table if not exists claim_ids (" +
" claimId text, " +
" name text, " +
" txid text)")
return self.db.runInteraction(create_tables)
def _clean_bad_records(self):
d = self.db.runQuery("delete from name_metadata where length(txid) > 64 or txid is null")
return d
def _save_name_metadata(self, name, txid, sd_hash): def _save_name_metadata(self, name, txid, sd_hash):
d = self.db.runQuery("select * from name_metadata where name=? and txid=? and sd_hash=?", (name, txid, sd_hash)) assert len(txid) == 64, "That's not a txid: %s" % str(txid)
d.addCallback(lambda r: self.db.runQuery("insert into name_metadata values (?, ?, ?)", (name, txid, sd_hash)) d = self.db.runQuery("delete from name_metadata where name=? and txid=? and sd_hash=?", (name, txid, sd_hash))
if not len(r) else None) d.addCallback(lambda _: self.db.runQuery("insert into name_metadata values (?, ?, ?)", (name, txid, sd_hash)))
return d return d
def _get_claim_metadata_for_sd_hash(self, sd_hash): def _get_claim_metadata_for_sd_hash(self, sd_hash):
d = self.db.runQuery("select name, txid from name_metadata where sd_hash=?", (sd_hash,)) d = self.db.runQuery("select name, txid from name_metadata where sd_hash=?", (sd_hash,))
d.addCallback(lambda r: r[0] if len(r) else None) d.addCallback(lambda r: r[0] if r else None)
return d
def _update_claimid(self, claim_id, name, txid):
assert len(txid) == 64, "That's not a txid: %s" % str(txid)
d = self.db.runQuery("delete from claim_ids where claimId=? and name=? and txid=?", (claim_id, name, txid))
d.addCallback(lambda r: self.db.runQuery("insert into claim_ids values (?, ?, ?)", (claim_id, name, txid)))
d.addCallback(lambda _: claim_id)
return d
def _get_claimid_for_tx(self, name, txid):
assert len(txid) == 64, "That's not a txid: %s" % str(txid)
d = self.db.runQuery("select claimId from claim_ids where name=? and txid=?", (name, txid))
d.addCallback(lambda r: r[0][0] if r else None)
return d return d
######### Must be overridden ######### ######### Must be overridden #########
@ -567,6 +652,9 @@ class LBRYWallet(object):
def get_name_claims(self): def get_name_claims(self):
return defer.fail(NotImplementedError()) return defer.fail(NotImplementedError())
def _get_claims_for_name(self, name):
return defer.fail(NotImplementedError())
def _check_first_run(self): def _check_first_run(self):
return defer.fail(NotImplementedError()) return defer.fail(NotImplementedError())
@ -582,7 +670,10 @@ class LBRYWallet(object):
def _send_abandon(self, txid, address, amount): def _send_abandon(self, txid, address, amount):
return defer.fail(NotImplementedError()) return defer.fail(NotImplementedError())
def _update_name(self, txid, value, amount): def _send_name_claim_update(self, name, claim_id, txid, value, amount):
return defer.fail(NotImplementedError())
def _support_claim(self, name, claim_id, amount):
return defer.fail(NotImplementedError()) return defer.fail(NotImplementedError())
def _do_send_many(self, payments_to_send): def _do_send_many(self, payments_to_send):
@ -717,9 +808,15 @@ class LBRYcrdWallet(LBRYWallet):
def _send_abandon(self, txid, address, amount): def _send_abandon(self, txid, address, amount):
return threads.deferToThread(self._send_abandon_rpc, txid, address, amount) return threads.deferToThread(self._send_abandon_rpc, txid, address, amount)
def _update_name(self, txid, value, amount): def _send_name_claim_update(self, name, claim_id, txid, value, amount):
return threads.deferToThread(self._update_name_rpc, txid, value, amount) return threads.deferToThread(self._update_name_rpc, txid, value, amount)
def _support_claim(self, name, claim_id, amount):
return threads.deferToThread(self._support_claim_rpc, name, claim_id, amount)
def _get_claims_for_name(self, name):
return threads.deferToThread(self._get_claims_for_name_rpc, name)
def get_claims_from_tx(self, txid): def get_claims_from_tx(self, txid):
return threads.deferToThread(self._get_claims_from_tx_rpc, txid) return threads.deferToThread(self._get_claims_from_tx_rpc, txid)
@ -854,6 +951,11 @@ class LBRYcrdWallet(LBRYWallet):
rpc_conn = self._get_rpc_conn() rpc_conn = self._get_rpc_conn()
return rpc_conn.getclaimsfortx(txid) return rpc_conn.getclaimsfortx(txid)
@_catch_connection_error
def _get_claims_for_name_rpc(self, name):
rpc_conn = self._get_rpc_conn()
return rpc_conn.getclaimsforname(name)
@_catch_connection_error @_catch_connection_error
def _get_nametrie_rpc(self): def _get_nametrie_rpc(self):
rpc_conn = self._get_rpc_conn() rpc_conn = self._get_rpc_conn()
@ -874,6 +976,7 @@ class LBRYcrdWallet(LBRYWallet):
rpc_conn = self._get_rpc_conn() rpc_conn = self._get_rpc_conn()
return rpc_conn.getvalueforname(name) return rpc_conn.getvalueforname(name)
@_catch_connection_error
def _update_name_rpc(self, txid, value, amount): def _update_name_rpc(self, txid, value, amount):
rpc_conn = self._get_rpc_conn() rpc_conn = self._get_rpc_conn()
return rpc_conn.updateclaim(txid, value, amount) return rpc_conn.updateclaim(txid, value, amount)
@ -889,6 +992,11 @@ class LBRYcrdWallet(LBRYWallet):
elif 'message' in e.error: elif 'message' in e.error:
raise ValueError(e.error['message']) raise ValueError(e.error['message'])
@_catch_connection_error
def _support_claim_rpc(self, name, claim_id, amount):
rpc_conn = self._get_rpc_conn()
return rpc_conn.supportclaim(name, claim_id, amount)
@_catch_connection_error @_catch_connection_error
def _get_num_addresses_rpc(self): def _get_num_addresses_rpc(self):
rpc_conn = self._get_rpc_conn() rpc_conn = self._get_rpc_conn()
@ -1102,6 +1210,25 @@ class LBRYumWallet(LBRYWallet):
d.addCallback(self._broadcast_transaction) d.addCallback(self._broadcast_transaction)
return d return d
def _get_claims_for_name(self, name):
cmd = known_commands['getclaimsforname']
func = getattr(self.cmd_runner, cmd.name)
return threads.deferToThread(func, name)
def _send_name_claim_update(self, name, claim_id, txid, value, amount):
def send_claim_update(address):
decoded_claim_id = claim_id.decode('hex')[::-1]
metadata = Metadata(value).as_json()
log.info("updateclaim %s %s %f %s %s '%s'", txid, address, amount, name, decoded_claim_id.encode('hex'), json.dumps(metadata))
cmd = known_commands['updateclaim']
func = getattr(self.cmd_runner, cmd.name)
return threads.deferToThread(func, txid, address, amount, name, decoded_claim_id, metadata)
d = self.get_new_address()
d.addCallback(send_claim_update)
d.addCallback(self._broadcast_transaction)
return d
def _get_decoded_tx(self, raw_tx): def _get_decoded_tx(self, raw_tx):
tx = Transaction(raw_tx) tx = Transaction(raw_tx)
decoded_tx = {} decoded_tx = {}
@ -1113,18 +1240,33 @@ class LBRYumWallet(LBRYWallet):
return decoded_tx return decoded_tx
def _send_abandon(self, txid, address, amount): def _send_abandon(self, txid, address, amount):
log.info("Abandon " + str(txid) + " " + str(address) + " " + str(amount)) log.info("Abandon %s %s %f" % (txid, address, amount))
cmd = known_commands['abandonclaim'] cmd = known_commands['abandonclaim']
func = getattr(self.cmd_runner, cmd.name) func = getattr(self.cmd_runner, cmd.name)
d = threads.deferToThread(func, txid, address, amount) d = threads.deferToThread(func, txid, address, amount)
d.addCallback(self._broadcast_transaction) d.addCallback(self._broadcast_transaction)
return d return d
def _support_claim(self, name, claim_id, amount):
def _send_support(d, a, n, c):
cmd = known_commands['supportclaim']
func = getattr(self.cmd_runner, cmd.name)
d = threads.deferToThread(func, d, a, n, c)
return d
d = self.get_new_address()
d.addCallback(lambda address: _send_support(address, amount, name, claim_id))
d.addCallback(self._broadcast_transaction)
return d
def _broadcast_transaction(self, raw_tx): def _broadcast_transaction(self, raw_tx):
log.info("Broadcast: " + str(raw_tx)) def _log_tx(r):
log.info("Broadcast tx: %s", r)
return r
cmd = known_commands['broadcast'] cmd = known_commands['broadcast']
func = getattr(self.cmd_runner, cmd.name) func = getattr(self.cmd_runner, cmd.name)
d = threads.deferToThread(func, raw_tx) d = threads.deferToThread(func, raw_tx)
d.addCallback(_log_tx)
d.addCallback(lambda r: r if len(r) == 64 else defer.fail(Exception("Transaction rejected")))
d.addCallback(self._save_wallet) d.addCallback(self._save_wallet)
return d return d

View file

@ -48,7 +48,7 @@ class DBLBRYFileMetadataManager(object):
return self._add_blobs_to_stream(stream_hash, blobs, ignore_duplicate_error=True) return self._add_blobs_to_stream(stream_hash, blobs, ignore_duplicate_error=True)
def get_blobs_for_stream(self, stream_hash, start_blob=None, end_blob=None, count=None, reverse=False): def get_blobs_for_stream(self, stream_hash, start_blob=None, end_blob=None, count=None, reverse=False):
log.info("Getting blobs for a stream. Count is %s", str(count)) log.debug("Getting blobs for a stream. Count is %s", str(count))
def get_positions_of_start_and_end(): def get_positions_of_start_and_end():
if start_blob is not None: if start_blob is not None:

View file

@ -27,6 +27,7 @@ class ManagedLBRYFileDownloader(LBRYFileSaver):
self.sd_hash = None self.sd_hash = None
self.txid = None self.txid = None
self.uri = None self.uri = None
self.claim_id = None
self.rowid = rowid self.rowid = rowid
self.lbry_file_manager = lbry_file_manager self.lbry_file_manager = lbry_file_manager
self.saving_status = False self.saving_status = False
@ -43,10 +44,16 @@ class ManagedLBRYFileDownloader(LBRYFileSaver):
return d return d
def _save_claim_id(claim_id):
self.claim_id = claim_id
return defer.succeed(None)
def _save_claim(name, txid): def _save_claim(name, txid):
self.uri = name self.uri = name
self.txid = txid self.txid = txid
return defer.succeed(None) d = self.wallet.get_claimid(name, txid)
d.addCallback(_save_claim_id)
return d
d.addCallback(_save_sd_hash) d.addCallback(_save_sd_hash)
d.addCallback(lambda r: _save_claim(r[0], r[1]) if r else None) d.addCallback(lambda r: _save_claim(r[0], r[1]) if r else None)

View file

@ -80,13 +80,16 @@ class LBRYFileManager(object):
d.addCallback(lambda downloader: downloader.restore()) d.addCallback(lambda downloader: downloader.restore())
return d return d
def log_error(err): def log_error(err, rowid, stream_hash, options):
log.error("An error occurred while starting a lbry file: %s", err.getErrorMessage()) log.error("An error occurred while starting a lbry file: %s", err.getErrorMessage())
log.error(rowid)
log.error(stream_hash)
log.error(options)
def start_lbry_files(lbry_files_and_options): def start_lbry_files(lbry_files_and_options):
for rowid, stream_hash, options in lbry_files_and_options: for rowid, stream_hash, options in lbry_files_and_options:
d = set_options_and_restore(rowid, stream_hash, options) d = set_options_and_restore(rowid, stream_hash, options)
d.addErrback(log_error) d.addErrback(lambda err: log_error(err, rowid, stream_hash, options))
return True return True
d = self._get_all_lbry_files() d = self._get_all_lbry_files()

View file

@ -39,6 +39,7 @@ from lbrynet.lbrynet_daemon.LBRYDownloader import GetStream
from lbrynet.lbrynet_daemon.LBRYPublisher import Publisher from lbrynet.lbrynet_daemon.LBRYPublisher import Publisher
from lbrynet.lbrynet_daemon.LBRYExchangeRateManager import ExchangeRateManager from lbrynet.lbrynet_daemon.LBRYExchangeRateManager import ExchangeRateManager
from lbrynet.lbrynet_daemon.Lighthouse import LighthouseClient from lbrynet.lbrynet_daemon.Lighthouse import LighthouseClient
from lbrynet.core.LBRYMetadata import Metadata
from lbrynet.core import log_support from lbrynet.core import log_support
from lbrynet.core import utils from lbrynet.core import utils
from lbrynet.core.LBRYMetadata import verify_name_characters from lbrynet.core.LBRYMetadata import verify_name_characters
@ -376,6 +377,7 @@ class LBRYDaemon(jsonrpc.JSONRPC):
log.info("Done writing lbrycrd.conf") log.info("Done writing lbrycrd.conf")
def _responseFailed(self, err, call): def _responseFailed(self, err, call):
log.error(err.getTraceback())
call.cancel() call.cancel()
def render(self, request): def render(self, request):
@ -1125,11 +1127,14 @@ class LBRYDaemon(jsonrpc.JSONRPC):
def _get_est_cost(self, name): def _get_est_cost(self, name):
def _check_est(d, name): def _check_est(d, name):
if isinstance(d.result, float): try:
log.info("Cost est for lbry://" + name + ": " + str(d.result) + "LBC") if d.result:
else: log.info("Cost est for lbry://" + name + ": " + str(d.result) + "LBC")
log.info("Timeout estimating cost for lbry://" + name + ", using key fee") return defer.succeed(None)
d.cancel() except AttributeError:
pass
log.info("Timeout estimating cost for lbry://" + name + ", using key fee")
d.cancel()
return defer.succeed(None) return defer.succeed(None)
def _add_key_fee(data_cost): def _add_key_fee(data_cost):
@ -1229,7 +1234,7 @@ class LBRYDaemon(jsonrpc.JSONRPC):
'stream_name': f.stream_name, 'stream_name': f.stream_name,
'suggested_file_name': f.suggested_file_name, 'suggested_file_name': f.suggested_file_name,
'upload_allowed': f.upload_allowed, 'sd_hash': f.sd_hash, 'upload_allowed': f.upload_allowed, 'sd_hash': f.sd_hash,
'lbry_uri': f.uri, 'txid': f.txid, 'lbry_uri': f.uri, 'txid': f.txid, 'claim_id': f.claim_id,
'total_bytes': size, 'total_bytes': size,
'written_bytes': written_bytes, 'code': status[0], 'written_bytes': written_bytes, 'code': status[0],
'message': message}) 'message': message})
@ -1241,7 +1246,7 @@ class LBRYDaemon(jsonrpc.JSONRPC):
'points_paid': f.points_paid, 'stopped': f.stopped, 'stream_hash': f.stream_hash, 'points_paid': f.points_paid, 'stopped': f.stopped, 'stream_hash': f.stream_hash,
'stream_name': f.stream_name, 'suggested_file_name': f.suggested_file_name, 'stream_name': f.stream_name, 'suggested_file_name': f.suggested_file_name,
'upload_allowed': f.upload_allowed, 'sd_hash': f.sd_hash, 'total_bytes': size, 'upload_allowed': f.upload_allowed, 'sd_hash': f.sd_hash, 'total_bytes': size,
'written_bytes': written_bytes, 'lbry_uri': f.uri, 'txid': f.txid, 'written_bytes': written_bytes, 'lbry_uri': f.uri, 'txid': f.txid, 'claim_id': f.claim_id,
'code': status[0], 'message': status[1]}) 'code': status[0], 'message': status[1]})
return d return d
@ -1272,7 +1277,7 @@ class LBRYDaemon(jsonrpc.JSONRPC):
d = self._get_lbry_file_by_sd_hash(val) d = self._get_lbry_file_by_sd_hash(val)
elif search_by == "file_name": elif search_by == "file_name":
d = self._get_lbry_file_by_file_name(val) d = self._get_lbry_file_by_file_name(val)
d.addCallback(_log_get_lbry_file) # d.addCallback(_log_get_lbry_file)
if return_json: if return_json:
d.addCallback(_get_json_for_return) d.addCallback(_get_json_for_return)
return d return d
@ -1638,11 +1643,15 @@ class LBRYDaemon(jsonrpc.JSONRPC):
""" """
def _convert_amount_to_float(r): def _convert_amount_to_float(r):
r['amount'] = float(r['amount']) / 10**8 if not r:
return r return False
else:
r['amount'] = float(r['amount']) / 10**8
return r
name = p['name'] name = p['name']
d = self.session.wallet.get_claim_info(name) txid = p.get('txid', None)
d = self.session.wallet.get_claim_info(name, txid)
d.addCallback(_convert_amount_to_float) d.addCallback(_convert_amount_to_float)
d.addCallback(lambda r: self._render_response(r, OK_CODE)) d.addCallback(lambda r: self._render_response(r, OK_CODE))
return d return d
@ -1771,7 +1780,7 @@ class LBRYDaemon(jsonrpc.JSONRPC):
List of search results List of search results
""" """
# TODO: change this function to "search", and use cached stream size info from the search server # TODO: change this function to "search"
if 'search' in p.keys(): if 'search' in p.keys():
search = p['search'] search = p['search']
@ -1840,26 +1849,31 @@ class LBRYDaemon(jsonrpc.JSONRPC):
Claim txid Claim txid
""" """
def _set_address(address, currency, m):
log.info("Generated new address for key fee: " + str(address))
m['fee'][currency]['address'] = address
return m
name = p['name'] name = p['name']
log.info("Publish: ")
log.info(p)
try: try:
verify_name_characters(name) verify_name_characters(name)
except: except AssertionError:
log.error("Bad name") log.error("Bad name")
return defer.fail(InvalidNameError("Bad name")) return defer.fail(InvalidNameError("Bad name"))
bid = p['bid'] bid = p['bid']
file_path = p['file_path']
metadata = p['metadata']
def _set_address(address, currency): try:
log.info("Generated new address for key fee: " + str(address)) metadata = Metadata(p['metadata'])
metadata['fee'][currency]['address'] = address make_lbry_file = False
return defer.succeed(None) except AssertionError:
make_lbry_file = True
def _delete_data(lbry_file): metadata = p['metadata']
txid = lbry_file.txid file_path = p['file_path']
d = self._delete_lbry_file(lbry_file, delete_file=False)
d.addCallback(lambda _: txid)
return d
if not self.pending_claim_checker.running: if not self.pending_claim_checker.running:
self.pending_claim_checker.start(30) self.pending_claim_checker.start(30)
@ -1873,15 +1887,16 @@ class LBRYDaemon(jsonrpc.JSONRPC):
for c in metadata['fee']: for c in metadata['fee']:
if 'address' not in metadata['fee'][c]: if 'address' not in metadata['fee'][c]:
d.addCallback(lambda _: self.session.wallet.get_new_address()) d.addCallback(lambda _: self.session.wallet.get_new_address())
d.addCallback(lambda addr: _set_address(addr, c)) d.addCallback(lambda addr: _set_address(addr, c, metadata))
else:
pub = Publisher(self.session, self.lbry_file_manager, self.session.wallet) d.addCallback(lambda _: metadata)
d.addCallback(lambda _: self._get_lbry_file_by_uri(name)) if make_lbry_file:
d.addCallbacks(lambda l: None if not l else _delete_data(l), lambda _: None) pub = Publisher(self.session, self.lbry_file_manager, self.session.wallet)
d.addCallback(lambda r: pub.start(name, file_path, bid, metadata, r)) d.addCallback(lambda meta: pub.start(name, file_path, bid, meta))
else:
d.addCallback(lambda meta: self.session.wallet.claim_name(name, bid, meta))
d.addCallback(lambda txid: self._add_to_pending_claims(name, txid)) d.addCallback(lambda txid: self._add_to_pending_claims(name, txid))
d.addCallback(lambda r: self._render_response(r, OK_CODE)) d.addCallback(lambda r: self._render_response(r, OK_CODE))
d.addErrback(lambda err: self._render_response(err.getTraceback(), BAD_REQUEST))
return d return d
@ -1911,6 +1926,25 @@ class LBRYDaemon(jsonrpc.JSONRPC):
return d return d
def jsonrpc_support_claim(self, p):
"""
Support a name claim
Args:
'name': name
'claim_id': claim id of claim to support
'amount': amount to support by
Return:
txid
"""
name = p['name']
claim_id = p['claim_id']
amount = p['amount']
d = self.session.wallet.support_claim(name, claim_id, amount)
d.addCallback(lambda r: self._render_response(r, OK_CODE))
return d
def jsonrpc_get_name_claims(self): def jsonrpc_get_name_claims(self):
""" """
Get my name claims Get my name claims
@ -1934,6 +1968,21 @@ class LBRYDaemon(jsonrpc.JSONRPC):
return d return d
def jsonrpc_get_claims_for_name(self, p):
"""
Get claims for a name
Args:
'name': name
Returns
list of name claims
"""
name = p['name']
d = self.session.wallet.get_claims_for_name(name)
d.addCallback(lambda r: self._render_response(r, OK_CODE))
return d
def jsonrpc_get_transaction_history(self): def jsonrpc_get_transaction_history(self):
""" """
Get transaction history Get transaction history
@ -2433,7 +2482,7 @@ class _ResolveNameHelper(object):
d = self.wallet.get_stream_info_for_name(self.name) d = self.wallet.get_stream_info_for_name(self.name)
d.addCallbacks(self._cache_stream_info, lambda _: defer.fail(UnknownNameError)) d.addCallbacks(self._cache_stream_info, lambda _: defer.fail(UnknownNameError))
else: else:
log.info("Returning cached stream info for lbry://%s", self.name) log.debug("Returning cached stream info for lbry://%s", self.name)
d = defer.succeed(self.name_data['claim_metadata']) d = defer.succeed(self.name_data['claim_metadata'])
return d return d

View file

@ -42,7 +42,7 @@ class Publisher(object):
self.stream_hash = None self.stream_hash = None
self.metadata = {} self.metadata = {}
def start(self, name, file_path, bid, metadata, old_txid): def start(self, name, file_path, bid, metadata):
def _show_result(): def _show_result():
log.info("Published %s --> lbry://%s txid: %s", self.file_name, self.publish_name, self.txid) log.info("Published %s --> lbry://%s txid: %s", self.file_name, self.publish_name, self.txid)
@ -52,7 +52,6 @@ class Publisher(object):
self.file_path = file_path self.file_path = file_path
self.bid_amount = bid self.bid_amount = bid
self.metadata = metadata self.metadata = metadata
self.old_txid = old_txid
d = self._check_file_path(self.file_path) d = self._check_file_path(self.file_path)
d.addCallback(lambda _: create_lbry_file(self.session, self.lbry_file_manager, d.addCallback(lambda _: create_lbry_file(self.session, self.lbry_file_manager,
@ -105,21 +104,12 @@ class Publisher(object):
self.metadata['content-type'] = mimetypes.guess_type(os.path.join(self.lbry_file.download_directory, self.metadata['content-type'] = mimetypes.guess_type(os.path.join(self.lbry_file.download_directory,
self.lbry_file.file_name))[0] self.lbry_file.file_name))[0]
self.metadata['ver'] = CURRENT_METADATA_VERSION self.metadata['ver'] = CURRENT_METADATA_VERSION
m = Metadata(self.metadata)
if self.old_txid:
d = self.wallet.abandon_name(self.old_txid)
d.addCallback(lambda tx: log.info("Abandoned tx %s" % str(tx)))
d.addCallback(lambda _: self.wallet.claim_name(self.publish_name,
self.bid_amount,
Metadata(self.metadata)))
else:
d = self.wallet.claim_name(self.publish_name,
self.bid_amount,
Metadata(self.metadata))
def set_tx_hash(txid): def set_tx_hash(txid):
self.txid = txid self.txid = txid
d = self.wallet.claim_name(self.publish_name, self.bid_amount, m)
d.addCallback(set_tx_hash) d.addCallback(set_tx_hash)
return d return d
@ -134,4 +124,4 @@ class Publisher(object):
log.error(error_message) log.error(error_message)
log.error(message, str(self.file_name), str(self.publish_name), err.getTraceback()) log.error(message, str(self.file_name), str(self.publish_name), err.getTraceback())
return defer.succeed(error_message) return defer.fail(Exception("Publish failed"))