From 2a8a984efa0990349c1e52862bdf959bba53905f Mon Sep 17 00:00:00 2001 From: Jack Robison Date: Sun, 23 Apr 2017 18:16:03 -0400 Subject: [PATCH 1/2] add claim and uri caching to wallet and wallet storage --- lbrynet/core/Wallet.py | 491 +++++++++++++----- .../EncryptedFileDownloader.py | 2 +- lbrynet/lbrynet_daemon/Daemon.py | 13 +- 3 files changed, 379 insertions(+), 127 deletions(-) diff --git a/lbrynet/core/Wallet.py b/lbrynet/core/Wallet.py index eec5057eb..d03ebdd8c 100644 --- a/lbrynet/core/Wallet.py +++ b/lbrynet/core/Wallet.py @@ -1,6 +1,8 @@ import datetime import logging import os +import json +import time from twisted.internet import threads, reactor, defer, task from twisted.python.failure import Failure @@ -23,10 +25,11 @@ from lbrynet.core.sqlite_helpers import rerun_if_locked from lbrynet.interfaces import IRequestCreator, IQueryHandlerFactory, IQueryHandler, IWallet from lbrynet.core.client.ClientRequest import ClientRequest from lbrynet.core.Error import RequestCanceledError, InsufficientFundsError, UnknownNameError -from lbrynet.db_migrator.migrate1to2 import UNSET_NOUT log = logging.getLogger(__name__) +CLAIM_CACHE_TIME = 600 + class ReservedPoints(object): def __init__(self, identifier, amount): @@ -60,6 +63,50 @@ class ClaimOutpoint(dict): return not self.__eq__(compare) +class CachedClaim(object): + def __init__(self, claim_id, claim, claim_sequence, address, height, amount, supports, + channal_name, signature_is_valid, cache_timestamp, name, txid, nout): + self.claim_id = claim_id + self.claim = claim + self.claim_sequence = claim_sequence + self.address = address + self.height = height + self.amount = amount + self.supports = [] if not supports else json.loads(supports) + self.effective_amount = self.amount + sum([x['amount'] for x in self.supports]) + self.channel_name = channal_name + self.signature_is_valid = signature_is_valid + self.cache_timestamp = cache_timestamp + self.name = name + self.txid = txid + self.nout = nout + + def response_dict(self, check_expires=True): + if check_expires and (time.time() - int(self.cache_timestamp)) > CLAIM_CACHE_TIME: + return + claim = { + "height": self.height, + "address": self.address, + "claim_id": self.claim_id, + "claim_sequence": self.claim_sequence, + "effective_amount": self.effective_amount, + "has_signature": self.claim.has_signature, + "name": self.name, + "hex": self.claim.serialized.encode('hex'), + "value": self.claim.claim_dict, + "txid": self.txid, + "amount": self.amount, + "decoded_claim": True, + "supports": self.supports, + "nout": self.nout + } + if self.channel_name is not None: + claim['channel_name'] = self.channel_name + if self.signature_is_valid is not None: + claim['signature_is_valid'] = bool(self.signature_is_valid) + return claim + + class MetaDataStorage(object): def load(self): return defer.succeed(True) @@ -76,14 +123,38 @@ class MetaDataStorage(object): def update_claimid(self, claim_id, name, claim_outpoint): return defer.succeed(True) - def get_claimid_for_tx(self, name, claim_outpoint): + def get_claimid_for_tx(self, claim_outpoint): return defer.succeed(True) + @defer.inlineCallbacks + def get_cached_claim(self, claim_id, check_expire=True): + cache_info = yield self._get_cached_claim(claim_id) + response = None + if cache_info: + cached_claim = CachedClaim(claim_id, *cache_info) + response = cached_claim.response_dict(check_expires=check_expire) + defer.returnValue(response) + + def _get_cached_claim(self, claim_id): + return defer.succeed(None) + + def save_claim_to_cache(self, claim_id, claim_sequence, claim, claim_address, height, amount, + supports, channel_name, signature_is_valid): + return defer.succeed(True) + + def save_claim_to_uri_cache(self, uri, claim_id, certificate_id=None): + return defer.succeed(None) + + def get_cached_claim_for_uri(self, uri, check_expire=True): + return defer.succeed(None) + class InMemoryStorage(MetaDataStorage): def __init__(self): self.metadata = {} self.claimids = {} + self.claim_dicts = {} + self.uri_cache = {} MetaDataStorage.__init__(self) def save_name_metadata(self, name, claim_outpoint, sd_hash): @@ -101,24 +172,59 @@ class InMemoryStorage(MetaDataStorage): self.claimids[(name, claim_outpoint['txid'], claim_outpoint['nout'])] = claim_id return defer.succeed(True) - def get_claimid_for_tx(self, name, claim_outpoint): - try: - return defer.succeed( - self.claimids[(name, claim_outpoint['txid'], claim_outpoint['nout'])]) - except KeyError: - return defer.succeed(None) + def get_claimid_for_tx(self, claim_outpoint): + result = None + for k, claim_id in self.claimids.iteritems(): + if k[1] == claim_outpoint['txid'] and k[2] == claim_outpoint['nout']: + result = claim_id + break + + return defer.succeed(result) + + def _get_cached_claim(self, claim_id): + claim_cache = self.claim_dicts.get(claim_id, None) + claim_tx_cache = None + for k, v in self.claimids.iteritems(): + if v == claim_id: + claim_tx_cache = k + break + + if claim_cache and claim_tx_cache: + cached_claim_args = tuple(claim_cache) + tuple(claim_tx_cache) + return defer.succeed(cached_claim_args) + return defer.succeed(None) + + def save_claim_to_cache(self, claim_id, claim_sequence, claim, claim_address, height, amount, + supports, channel_name, signature_is_valid): + self.claim_dicts[claim_id] = (claim, claim_sequence, claim_address, height, amount, + supports, channel_name, signature_is_valid, int(time.time())) + return defer.succeed(True) + + def save_claim_to_uri_cache(self, uri, claim_id, certificate_id=None): + self.uri_cache[uri] = (claim_id, certificate_id) + return defer.succeed(None) + + @defer.inlineCallbacks + def get_cached_claim_for_uri(self, uri, check_expire=True): + result = self.uri_cache.get(uri, None) + response = None + if result: + claim_id, certificate_id = result + response = yield self.get_cached_claim(claim_id, check_expire) + if response and certificate_id: + certificate = yield self.get_cached_claim(certificate_id, check_expire) + response['certificate'] = certificate['claim'] + defer.returnValue(response) class SqliteStorage(MetaDataStorage): def __init__(self, db_dir): self.db_dir = db_dir - self.db = None + self.db = adbapi.ConnectionPool('sqlite3', os.path.join(self.db_dir, "blockchainname.db"), + check_same_thread=False) MetaDataStorage.__init__(self) def load(self): - self.db = adbapi.ConnectionPool('sqlite3', os.path.join(self.db_dir, "blockchainname.db"), - check_same_thread=False) - def create_tables(transaction): transaction.execute("create table if not exists name_metadata (" + " name text, " + @@ -130,54 +236,162 @@ class SqliteStorage(MetaDataStorage): " name text, " + " txid text, " + " n integer)") + transaction.execute("CREATE TABLE IF NOT EXISTS claim_cache (" + + " row_id INTEGER PRIMARY KEY AUTOINCREMENT, " + + " claim_id TEXT UNIQUE NOT NULL, " + + " claim_sequence INTEGER, " + + " claim_address TEXT NOT NULL, " + + " height INTEGER NOT NULL, " + + " amount INTEGER NOT NULL, " + + " supports TEXT, " + + " claim_pb TEXT, " + + " channel_name TEXT, " + + " signature_is_valid BOOL, " + + " last_modified TEXT)") + transaction.execute("CREATE TABLE IF NOT EXISTS uri_cache (" + + " row_id INTEGER PRIMARY KEY AUTOINCREMENT, " + + " uri TEXT UNIQUE NOT NULL, " + + " cache_row INTEGER, " + + " certificate_row INTEGER, " + + " last_modified TEXT)") return self.db.runInteraction(create_tables) + @rerun_if_locked + @defer.inlineCallbacks 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, claim_outpoint, sd_hash): - d = self.db.runQuery( - "delete from name_metadata where name=? and txid=? and n=? and sd_hash=?", - (name, claim_outpoint['txid'], claim_outpoint['nout'], sd_hash)) - d.addCallback( - lambda _: self.db.runQuery( - "delete from name_metadata where name=? and txid=? and n=? and sd_hash=?", - (name, claim_outpoint['txid'], UNSET_NOUT, sd_hash))) - d.addCallback( - lambda _: self.db.runQuery( - "insert into name_metadata values (?, ?, ?, ?)", - (name, claim_outpoint['txid'], claim_outpoint['nout'], sd_hash))) - return d + yield self.db.runQuery("DELETE FROM name_metadata WHERE LENGTH(txid) > 64 OR txid IS NULL") + defer.returnValue(None) @rerun_if_locked + @defer.inlineCallbacks + def save_name_metadata(self, name, claim_outpoint, sd_hash): + # TODO: refactor the 'name_metadata' and 'claim_ids' tables to not be terrible + txid, nout = claim_outpoint['txid'], claim_outpoint['nout'] + record_exists = yield self.db.runQuery("SELECT COUNT(*) FROM name_metadata " + "WHERE name=? AND txid=? AND n=?", + (name, txid, nout)) + if not record_exists: + yield self.db.runOperation("INSERT INTO name_metadata VALUES (?, ?, ?, ?)", + (name, txid, nout, sd_hash)) + defer.returnValue(None) + + @rerun_if_locked + @defer.inlineCallbacks def get_claim_metadata_for_sd_hash(self, sd_hash): - d = self.db.runQuery("select name, txid, n from name_metadata where sd_hash=?", (sd_hash,)) - d.addCallback(lambda r: r[0] if r else None) - return d + result = yield self.db.runQuery("SELECT name, txid, n FROM name_metadata WHERE sd_hash=?", + (sd_hash, )) + response = None + if result: + response = result[0] + defer.returnValue(response) + @rerun_if_locked + @defer.inlineCallbacks def update_claimid(self, claim_id, name, claim_outpoint): - d = self.db.runQuery( - "delete from claim_ids where claimId=? and name=? and txid=? and n=?", - (claim_id, name, claim_outpoint['txid'], claim_outpoint['nout'])) - d.addCallback( - lambda _: self.db.runQuery( - "delete from claim_ids where claimId=? and name=? and txid=? and n=?", - (claim_id, name, claim_outpoint['txid'], UNSET_NOUT))) - d.addCallback( - lambda r: self.db.runQuery( - "insert into claim_ids values (?, ?, ?, ?)", - (claim_id, name, claim_outpoint['txid'], claim_outpoint['nout']))) - d.addCallback(lambda _: claim_id) - return d + txid, nout = claim_outpoint['txid'], claim_outpoint['nout'] + yield self.db.runOperation("INSERT OR IGNORE INTO claim_ids VALUES (?, ?, ?, ?)", + (claim_id, name, txid, nout)) + defer.returnValue(claim_id) - def get_claimid_for_tx(self, name, claim_outpoint): - d = self.db.runQuery( - "select claimId from claim_ids where name=? and txid=? and n=?", - (name, claim_outpoint['txid'], claim_outpoint['nout'])) - d.addCallback(lambda r: r[0][0] if r else None) - return d + @rerun_if_locked + @defer.inlineCallbacks + def get_claimid_for_tx(self, claim_outpoint): + result = yield self.db.runQuery("SELECT claimId FROM claim_ids " + "WHERE txid=? AND n=?", + (claim_outpoint['txid'], claim_outpoint['nout'])) + response = None + if result: + response = result[0][0] + defer.returnValue(response) + + @rerun_if_locked + @defer.inlineCallbacks + def _get_cached_claim(self, claim_id, check_expire=True): + r = yield self.db.runQuery("SELECT * FROM claim_cache WHERE claim_id=?", (claim_id, )) + claim_tx_info = yield self.db.runQuery("SELECT name, txid, n FROM claim_ids " + "WHERE claimId=?", (claim_id, )) + response = None + if r and claim_tx_info: + _, _, seq, claim_address, height, amount, supports, raw, chan_name, valid, ts = r[0] + last_modified = int(ts) + name, txid, nout = claim_tx_info[0] + claim = ClaimDict.deserialize(raw.decode('hex')) + response = (claim, seq, claim_address, height, amount, supports, + chan_name, valid, last_modified, name, txid, nout) + defer.returnValue(response) + + @rerun_if_locked + @defer.inlineCallbacks + def save_claim_to_cache(self, claim_id, claim_sequence, claim, claim_address, height, amount, + supports, channel_name, signature_is_valid): + serialized = claim.serialized.encode("hex") + supports = json.dumps([] or supports) + now = str(int(time.time())) + + yield self.db.runOperation("INSERT OR REPLACE INTO claim_cache(claim_sequence, " + " claim_id, claim_address, height, " + " amount, supports, claim_pb, " + " channel_name, signature_is_valid, " + " last_modified)" + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", + (claim_sequence, claim_id, claim_address, height, amount, + supports, serialized, channel_name, signature_is_valid, now)) + defer.returnValue(None) + + @rerun_if_locked + @defer.inlineCallbacks + def save_claim_to_uri_cache(self, uri, claim_id, certificate_id=None): + result = yield self.db.runQuery("SELECT row_id, last_modified FROM claim_cache " + "WHERE claim_id=?", (claim_id, )) + certificate_result = None + certificate_row = None + + if certificate_id: + certificate_result = yield self.db.runQuery("SELECT row_id FROM claim_cache " + "WHERE claim_id=?", (certificate_id, )) + if certificate_id is not None and certificate_result is None: + log.warning("Certificate is not in cache") + elif certificate_result: + certificate_row = certificate_result[0][0] + + if result: + cache_row, ts = result[0] + yield self.db.runOperation("INSERT OR REPLACE INTO uri_cache(uri, cache_row, " + " certificate_row, last_modified) " + "VALUES (?, ?, ?, ?)", + (uri, cache_row, certificate_row, + str(int(time.time())))) + else: + log.warning("Claim is not in cache") + defer.returnValue(None) + + @rerun_if_locked + @defer.inlineCallbacks + def get_cached_claim_for_uri(self, uri, check_expire=True): + result = yield self.db.runQuery("SELECT " + "claim.claim_id, cert.claim_id, uri_cache.last_modified " + "FROM uri_cache " + "INNER JOIN claim_cache as claim " + "ON uri_cache.cache_row=claim.row_id " + "LEFT OUTER JOIN claim_cache as cert " + "ON uri_cache.certificate_row=cert.row_id " + "WHERE uri_cache.uri=?", (uri, )) + response = None + if result: + claim_id, certificate_id, last_modified = result[0] + last_modified = int(last_modified) + if check_expire and time.time() - last_modified > CLAIM_CACHE_TIME: + defer.returnValue(None) + claim = yield self.get_cached_claim(claim_id) + if claim: + response = { + "claim": claim + } + if response and certificate_id is not None: + certificate = yield self.get_cached_claim(certificate_id) + response['certificate'] = certificate + defer.returnValue(response) class Wallet(object): @@ -230,9 +444,6 @@ class Wallet(object): def _update_claimid(self, claim_id, name, claim_outpoint): return self._storage.update_claimid(claim_id, name, claim_outpoint) - def _get_claimid_for_tx(self, name, claim_outpoint): - return self._storage.get_claimid_for_tx(name, claim_outpoint) - @staticmethod def log_stop_error(err): log.error("An error occurred stopping the wallet: %s", err.getTraceback()) @@ -452,42 +663,30 @@ class Wallet(object): ###### @defer.inlineCallbacks - def get_claim(self, claim_id): - claim = yield self._get_claim_by_claimid(claim_id) - if not claim: - log.warning("Claim does not exist: %s", claim_id) - defer.returnValue(None) - try: - decoded = smart_decode(claim['value']) - claim['value'] = decoded.claim_dict - claim['hex'] = decoded.serialized.encode('hex') - except DecodeError: - claim['hex'] = claim['value'] - claim['value'] = None - claim['error'] = "Failed to decode" - log.warning("Failed to decode claim value for lbry://%s#%s", claim['name'], - claim['claim_id']) - defer.returnValue(claim) + def get_cached_claim(self, claim_id, check_expire=True): + results = yield self._storage.get_cached_claim(claim_id, check_expire) + defer.returnValue(results) - def get_claimid(self, name, txid, nout): - def _get_id_for_return(claim_id): - if claim_id: - return defer.succeed(claim_id) + @defer.inlineCallbacks + def get_claim(self, claim_id, check_expire=True): + cached_claim = yield self.get_cached_claim(claim_id, check_expire) + if cached_claim: + result = cached_claim + else: + log.debug("Refreshing cached claim: %s", claim_id) + claim = yield self._get_claim_by_claimid(claim_id) + result = None + if claim: + result = yield self._handle_claim_result(claim) else: - d = self.get_claims_from_tx(txid) - d.addCallback( - lambda claims: next( - c for c in claims if c['name'] == name and - c['nout'] == claim_outpoint['nout'])) - d.addCallback( - lambda claim: self._update_claimid( - claim['claim_id'], name, ClaimOutpoint(txid, claim['nout']))) - return d + log.warning("Claim does not exist: %s", claim_id) + defer.returnValue(result) + @defer.inlineCallbacks + def get_claimid(self, txid, nout): claim_outpoint = ClaimOutpoint(txid, nout) - d = self._get_claimid_for_tx(name, claim_outpoint) - d.addCallback(_get_id_for_return) - return d + claim_id = yield self._storage.get_claimid_for_tx(claim_outpoint) + defer.returnValue(claim_id) @defer.inlineCallbacks def get_my_claim(self, name): @@ -501,19 +700,19 @@ class Wallet(object): defer.returnValue(my_claim) @defer.inlineCallbacks - def get_claim_info(self, name, txid=None, nout=None, claim_id=None): + def get_claim_info(self, name, txid=None, nout=None, claim_id=None, check_expire=True): if claim_id is not None: - results = yield self.get_claim(claim_id) + results = yield self.get_claim(claim_id, check_expire) if results['name'] != name: raise Exception("Name does not match claim referenced by id") elif txid is None or nout is None: results = yield self.get_claim_by_name(name) else: - results = yield self.get_claim_by_outpoint(ClaimOutpoint(txid, nout)) + results = yield self.get_claim_by_outpoint(ClaimOutpoint(txid, nout), check_expire) defer.returnValue(results) @defer.inlineCallbacks - def _handle_claim_result(self, results): + def _handle_claim_result(self, results, update_caches=True): if not results: raise UnknownNameError("No results to return") @@ -523,16 +722,35 @@ class Wallet(object): else: raise Exception(results['error']) + if 'certificate' in results: + try: + decoded = smart_decode(results['certificate']['value']) + claim_dict = decoded.claim_dict + outpoint = ClaimOutpoint(results['certificate']['txid'], + results['certificate']['nout']) + name = results['certificate']['name'] + results['certificate']['value'] = claim_dict + results['certificate']['hex'] = decoded.serialized.encode('hex') + if update_caches: + yield self._save_name_metadata(name, outpoint, decoded.source_hash) + yield self._update_claimid(results['certificate']['claim_id'], name, outpoint) + yield self._storage.save_claim_to_cache(results['certificate']['claim_id'], + results['certificate']['claim_sequence'], + decoded, results['certificate']['address'], + results['certificate']['height'], + results['certificate']['amount'], + results['certificate']['supports'], + None, + None) + except DecodeError: + pass + if 'claim' in results: claim = results['claim'] if 'has_signature' in claim and claim['has_signature']: if not claim['signature_is_valid']: log.warning("lbry://%s#%s has an invalid signature", claim['name'], claim['claim_id']) - decoded = ClaimDict.load_dict(claim['value']) - claim_dict = decoded.claim_dict - claim['value'] = claim_dict - defer.returnValue(claim) try: decoded = smart_decode(claim['value']) claim_dict = decoded.claim_dict @@ -540,24 +758,28 @@ class Wallet(object): name = claim['name'] claim['value'] = claim_dict claim['hex'] = decoded.serialized.encode('hex') - yield self._save_name_metadata(name, outpoint, decoded.source_hash) - yield self._update_claimid(claim['claim_id'], name, outpoint) + if update_caches: + yield self._save_name_metadata(name, outpoint, decoded.source_hash) + yield self._update_claimid(claim['claim_id'], name, outpoint) + yield self._storage.save_claim_to_cache(claim['claim_id'], + claim['claim_sequence'], + decoded, claim['address'], + claim['height'], + claim['amount'], claim['supports'], + claim.get('channel_name', None), + claim.get('signature_is_valid', None)) except DecodeError: claim['hex'] = claim['value'] claim['value'] = None claim['error'] = "Failed to decode value" - results = claim + results['claim'] = claim elif 'value' in results: if 'has_signature' in results and results['has_signature']: if not results['signature_is_valid']: log.warning("lbry://%s#%s has an invalid signature", results['name'], results['claim_id']) - decoded = ClaimDict.load_dict(results['value']) - claim_dict = decoded.claim_dict - results['value'] = claim_dict - defer.returnValue(results) try: decoded = ClaimDict.load_dict(results['value']) claim_dict = decoded.claim_dict @@ -565,8 +787,18 @@ class Wallet(object): claim_err = None outpoint = ClaimOutpoint(results['txid'], results['nout']) name = results['name'] - yield self._save_name_metadata(name, outpoint, decoded.source_hash) - yield self._update_claimid(results['claim_id'], name, outpoint) + if update_caches: + yield self._save_name_metadata(name, outpoint, decoded.source_hash) + yield self._update_claimid(results['claim_id'], name, outpoint) + yield self._storage.save_claim_to_cache(results['claim_id'], + results.get('claim_sequence', None), + decoded, results['address'], + results['height'], results['amount'], + results.get('supports', '[]'), + results.get('channel_name', None), + results.get('signature_is_valid', + None)) + except DecodeError: claim_dict = None claim_hex = results['value'] @@ -576,33 +808,46 @@ class Wallet(object): results['hex'] = claim_hex results['value'] = claim_dict - log.info("get claim info lbry://%s#%s", results['name'], results['claim_id']) defer.returnValue(results) @defer.inlineCallbacks - def resolve_uri(self, uri): - resolve_results = yield self._get_value_for_uri(uri) - if 'claim' in resolve_results: - formatted = yield self._handle_claim_result(resolve_results) - resolve_results['claim'] = formatted - result = resolve_results - elif 'claims_in_channel' in resolve_results: - claims_for_return = [] - for claim in resolve_results['claims_in_channel']: - formatted = yield self._handle_claim_result(claim) - claims_for_return.append(formatted) - resolve_results['claims_in_channel'] = claims_for_return - result = resolve_results - elif 'error' in resolve_results: - raise Exception(resolve_results['error']) + def resolve_uri(self, uri, check_cache=True): + cached_claim = None + if check_cache: + cached_claim = yield self._storage.get_cached_claim_for_uri(uri, check_cache) + if cached_claim: + log.debug("Using cached results for %s", uri) + resolve_results = cached_claim else: - result = None + log.info("Resolving %s", uri) + resolve_results = yield self._get_value_for_uri(uri) + + claim_id = None + if resolve_results and 'claim' in resolve_results: + claim_id = resolve_results['claim']['claim_id'] + certificate_id = None + if resolve_results and 'certificate' in resolve_results: + certificate_id = resolve_results['certificate']['claim_id'] + + result = yield self._handle_claim_result(resolve_results, cached_claim is None) + if claim_id: + yield self._storage.save_claim_to_uri_cache(uri, claim_id, certificate_id) + defer.returnValue(result) @defer.inlineCallbacks - def get_claim_by_outpoint(self, claim_outpoint): - claim = yield self._get_claim_by_outpoint(claim_outpoint['txid'], claim_outpoint['nout']) - result = yield self._handle_claim_result(claim) + def get_claim_by_outpoint(self, claim_outpoint, check_expire=True): + claim_id = yield self._storage.get_claimid_for_tx(claim_outpoint) + txid, nout = claim_outpoint['txid'], claim_outpoint['nout'] + if claim_id: + cached_claim = yield self._storage.get_cached_claim(claim_id, check_expire) + else: + cached_claim = None + if not cached_claim: + claim = yield self._get_claim_by_outpoint(txid, nout) + result = yield self._handle_claim_result(claim) + else: + result = cached_claim defer.returnValue(result) @defer.inlineCallbacks @@ -1124,7 +1369,7 @@ class LBRYumWallet(Wallet): def _do_send_many(self, payments_to_send): def broadcast_send_many(paytomany_out): if 'hex' not in paytomany_out: - raise Exception('Unepxected paytomany output:{}'.format(paytomany_out)) + raise Exception('Unexpected paytomany output:{}'.format(paytomany_out)) return self._broadcast_transaction(paytomany_out['hex']) log.debug("Doing send many. payments to send: %s", str(payments_to_send)) diff --git a/lbrynet/lbryfilemanager/EncryptedFileDownloader.py b/lbrynet/lbryfilemanager/EncryptedFileDownloader.py index f2776e650..887e7966a 100644 --- a/lbrynet/lbryfilemanager/EncryptedFileDownloader.py +++ b/lbrynet/lbryfilemanager/EncryptedFileDownloader.py @@ -123,7 +123,7 @@ class ManagedEncryptedFileDownloader(EncryptedFileSaver): self.outpoint = ClaimOutpoint(self.txid, self.nout) else: raise NoSuchSDHash(self.sd_hash) - self.claim_id = yield self.wallet.get_claimid(self.name, self.txid, self.nout) + self.claim_id = yield self.wallet.get_claimid(self.txid, self.nout) defer.returnValue(None) @defer.inlineCallbacks diff --git a/lbrynet/lbrynet_daemon/Daemon.py b/lbrynet/lbrynet_daemon/Daemon.py index 7064ef83c..2e5a2bef4 100644 --- a/lbrynet/lbrynet_daemon/Daemon.py +++ b/lbrynet/lbrynet_daemon/Daemon.py @@ -878,7 +878,7 @@ class Daemon(AuthJSONRPCServer): size = None message = None - claim = yield self.session.wallet.get_claim(lbry_file.claim_id) + claim = yield self.session.wallet.get_claim(lbry_file.claim_id, check_expire=False) if claim and 'value' in claim: metadata = claim['value'] @@ -915,7 +915,6 @@ class Daemon(AuthJSONRPCServer): 'suggested_file_name': lbry_file.suggested_file_name, 'sd_hash': lbry_file.sd_hash, 'name': lbry_file.name, - 'channel_name': channel_name, 'outpoint': outpoint, 'claim_id': lbry_file.claim_id, 'download_path': full_path, @@ -926,6 +925,8 @@ class Daemon(AuthJSONRPCServer): 'message': message, 'metadata': metadata } + if channel_name is not None: + result['channel_name'] = channel_name if has_signature is not None: result['has_signature'] = has_signature if signature_is_valid is not None: @@ -1394,7 +1395,13 @@ class Daemon(AuthJSONRPCServer): } """ try: - claim_results = yield self.session.wallet.get_claim_info(name, txid, nout, claim_id) + if claim_id: + claim_results = yield self.session.wallet.get_claim(claim_id) + elif txid and nout is not None: + outpoint = ClaimOutpoint(txid, nout) + claim_results = yield self.session.wallet.get_claim_by_outpoint(outpoint) + else: + claim_results = yield self.session.wallet.get_claim_by_name(name) result = format_json_out_amount_as_float(claim_results) except (TypeError, UnknownNameError): result = False From 18747d4349c5b4f58e6d2d9b08aff45291d58ca4 Mon Sep 17 00:00:00 2001 From: Jack Robison Date: Sun, 23 Apr 2017 20:16:50 -0400 Subject: [PATCH 2/2] update changelog --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b87557feb..50892247c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,12 @@ at anytime. * * + * Added optional `address` and `include_unconfirmed` params to `jsonrpc_wallet_balance` method + * Wait for subscriptions before announcing wallet has finished starting + * Cache claims in wallet storage for use looking claims up by id or outpoint + * Try to use cached claim info for `file_list` + * Convert wallet storage to inlinecallbacks + ### Fixed * *