diff --git a/lbrynet/extras/daemon/Daemon.py b/lbrynet/extras/daemon/Daemon.py index ed3887695..ae1a0321f 100644 --- a/lbrynet/extras/daemon/Daemon.py +++ b/lbrynet/extras/daemon/Daemon.py @@ -1697,7 +1697,7 @@ class Daemon(metaclass=JSONRPCServerType): claim_search [ | --name=] [--claim_id=] [--txid=] [--nout=] [--channel= | --channel_ids=...] [--valid_channel_signatures] [--invalid_channel_signatures] - [--is_controlling] [--release_time=] + [--is_controlling] [--release_time=] [--public_key_id=] [--timestamp=] [--creation_timestamp=] [--height=] [--creation_height=] [--activation_height=] [--expiration_height=] @@ -1730,6 +1730,9 @@ class Daemon(metaclass=JSONRPCServerType): --valid_channel_signatures : (bool) only return claims with valid channel signatures --invalid_channel_signatures : (bool) only return claims with invalid channel signatures --is_controlling : (bool) only return winning claims of their respective name + --public_key_id : (str) only return channels having this public key id, this is + the same key as used in the wallet file to map + channel certificate private keys: {'public_key_id': 'private key'} --height= : (int) last updated block height (supports equality constraints) --timestamp= : (int) last updated timestamp (supports equality constraints) --creation_height= : (int) created at block height (supports equality constraints) diff --git a/lbrynet/extras/daemon/json_response_encoder.py b/lbrynet/extras/daemon/json_response_encoder.py index 5862e71d0..423f99914 100644 --- a/lbrynet/extras/daemon/json_response_encoder.py +++ b/lbrynet/extras/daemon/json_response_encoder.py @@ -1,6 +1,6 @@ import logging from decimal import Decimal -from binascii import hexlify +from binascii import hexlify, unhexlify from datetime import datetime from json import JSONEncoder @@ -227,6 +227,10 @@ class JSONResponseEncoder(JSONEncoder): }) return file - @staticmethod - def encode_claim(claim): - return getattr(claim, claim.claim_type).to_dict() + def encode_claim(self, claim): + encoded = getattr(claim, claim.claim_type).to_dict() + if 'public_key' in encoded: + encoded['public_key_id'] = self.ledger.public_key_to_address( + unhexlify(encoded['public_key']) + ) + return encoded diff --git a/lbrynet/wallet/server/db.py b/lbrynet/wallet/server/db.py index 33c3aafaf..fb742c1d1 100644 --- a/lbrynet/wallet/server/db.py +++ b/lbrynet/wallet/server/db.py @@ -90,6 +90,7 @@ class SQLDB: -- claims which are channels is_channel bool not null, public_key_bytes bytes, + public_key_hash bytes, claims_in_channel integer, -- claims which are inside channels @@ -116,6 +117,7 @@ class SQLDB: create index if not exists claim_timestamp_idx on claim (timestamp); create index if not exists claim_height_idx on claim (height); create index if not exists claim_activation_height_idx on claim (activation_height); + create index if not exists claim_public_key_hash_idx on claim (public_key_hash); create index if not exists claim_effective_amount_idx on claim (effective_amount); create index if not exists claim_trending_group_idx on claim (trending_group); @@ -467,9 +469,16 @@ class SQLDB: if channels: self.db.executemany( - "UPDATE claim SET public_key_bytes=:public_key_bytes WHERE claim_hash=:claim_hash", [{ + """ + UPDATE claim SET + public_key_bytes=:public_key_bytes, + public_key_hash=:public_key_hash + WHERE claim_hash=:claim_hash""", [{ 'claim_hash': sqlite3.Binary(claim_hash), - 'public_key_bytes': sqlite3.Binary(txo.claim.channel.public_key_bytes) + 'public_key_bytes': sqlite3.Binary(txo.claim.channel.public_key_bytes), + 'public_key_hash': sqlite3.Binary( + self.ledger.address_to_hash160( + self.ledger.public_key_to_address(txo.claim.channel.public_key_bytes))) } for claim_hash, txo in channels.items()] ) @@ -684,6 +693,10 @@ class SQLDB: if 'name' in constraints: constraints['claim.normalized'] = normalize_name(constraints.pop('name')) + if 'public_key_id' in constraints: + constraints['claim.public_key_hash'] = sqlite3.Binary( + self.ledger.address_to_hash160(constraints.pop('public_key_id'))) + if 'channel' in constraints: channel_url = constraints.pop('channel') match = self._resolve_one(channel_url) @@ -759,7 +772,7 @@ class SQLDB: } SEARCH_PARAMS = { - 'name', 'claim_id', 'txid', 'nout', 'channel', 'channel_ids', + 'name', 'claim_id', 'txid', 'nout', 'channel', 'channel_ids', 'public_key_id', 'any_tags', 'all_tags', 'not_tags', 'any_locations', 'all_locations', 'not_locations', 'any_languages', 'all_languages', 'not_languages', diff --git a/setup.py b/setup.py index 50ba48881..c0a41efaf 100644 --- a/setup.py +++ b/setup.py @@ -23,7 +23,7 @@ setup( 'console_scripts': 'lbrynet=lbrynet.extras.cli:main' }, install_requires=[ - 'torba==0.5.4', + 'torba==0.5.5', 'aiohttp==3.5.4', 'aioupnp', 'appdirs==1.4.3', diff --git a/tests/integration/test_claim_commands.py b/tests/integration/test_claim_commands.py index d846ad87d..050d564c2 100644 --- a/tests/integration/test_claim_commands.py +++ b/tests/integration/test_claim_commands.py @@ -50,8 +50,10 @@ class ClaimSearchCommand(CommandTestCase): async def test_basic_claim_search(self): await self.create_channel() + channel_txo = self.channel['outputs'][0] channel2 = await self.channel_create('@abc', '0.1', allow_duplicate_name=True) - channel_id2 = channel2['outputs'][0]['claim_id'] + channel_txo2 = channel2['outputs'][0] + channel_id2 = channel_txo2['claim_id'] # finding a channel await self.assertFindsClaims([channel2, self.channel], name='@abc') @@ -60,6 +62,10 @@ class ClaimSearchCommand(CommandTestCase): await self.assertFindsClaim(self.channel, txid=self.channel['txid'], nout=0) await self.assertFindsClaim(channel2, claim_id=channel_id2) await self.assertFindsClaim(channel2, txid=channel2['txid'], nout=0) + await self.assertFindsClaim( + channel2, public_key_id=channel_txo2['value']['public_key_id']) + await self.assertFindsClaim( + self.channel, public_key_id=channel_txo['value']['public_key_id']) signed = await self.stream_create('on-channel-claim', '0.001', channel_id=self.channel_id) signed2 = await self.stream_create('on-channel-claim', '0.0001', channel_id=channel_id2,