fixed resolve to work with partial claim_ids

This commit is contained in:
Lex Berezhny 2019-05-26 13:21:26 -04:00
parent b6811d55cf
commit 786efa06dd
4 changed files with 69 additions and 15 deletions

View file

@ -138,7 +138,7 @@ class JSONResponseEncoder(JSONEncoder):
'hex': hexlify(tx.raw).decode(), 'hex': hexlify(tx.raw).decode(),
} }
def encode_output(self, txo, check_signature=True, include_meta=True): def encode_output(self, txo, check_signature=True):
tx_height = txo.tx_ref.height tx_height = txo.tx_ref.height
best_height = self.ledger.headers.height best_height = self.ledger.headers.height
output = { output = {
@ -171,11 +171,13 @@ class JSONResponseEncoder(JSONEncoder):
'name': txo.claim_name, 'name': txo.claim_name,
'normalized': txo.normalized_name, 'normalized': txo.normalized_name,
'claim_id': txo.claim_id, 'claim_id': txo.claim_id,
'permanent_url': txo.permanent_url 'permanent_url': txo.permanent_url,
'meta': self.encode_claim_meta(txo.meta)
}) })
if include_meta: if 'short_url' in output['meta']:
output['meta'] = self.encode_claim_meta(txo.meta) output['short_url'] = output['meta'].pop('short_url')
output['canonical_url'] = output['meta'].pop('canonical_url', None) if 'canonical_url' in output['meta']:
output['canonical_url'] = output['meta'].pop('canonical_url')
if txo.script.is_claim_name or txo.script.is_update_claim: if txo.script.is_claim_name or txo.script.is_update_claim:
try: try:
output['value'] = txo.claim output['value'] = txo.claim
@ -183,7 +185,7 @@ class JSONResponseEncoder(JSONEncoder):
if self.include_protobuf: if self.include_protobuf:
output['protobuf'] = hexlify(txo.claim.to_bytes()) output['protobuf'] = hexlify(txo.claim.to_bytes())
if txo.channel is not None: if txo.channel is not None:
output['signing_channel'] = self.encode_output(txo.channel, include_meta=False) output['signing_channel'] = self.encode_output(txo.channel)
if check_signature and txo.claim.is_signed: if check_signature and txo.claim.is_signed:
output['is_channel_signature_valid'] = False output['is_channel_signature_valid'] = False
if txo.channel: if txo.channel:

View file

@ -33,8 +33,8 @@ class Outputs:
if txo_message.WhichOneof('meta') == 'claim': if txo_message.WhichOneof('meta') == 'claim':
claim = txo_message.claim claim = txo_message.claim
txo.meta = { txo.meta = {
'short_url': claim.short_url, 'short_url': f'lbry://{claim.short_url}',
'canonical_url': claim.canonical_url or claim.short_url, 'canonical_url': f'lbry://{claim.canonical_url or claim.short_url}',
'is_controlling': claim.is_controlling, 'is_controlling': claim.is_controlling,
'activation_height': claim.activation_height, 'activation_height': claim.activation_height,
'expiration_height': claim.expiration_height, 'expiration_height': claim.expiration_height,

View file

@ -107,7 +107,9 @@ class SQLDB:
trending_global integer not null default 0 trending_global integer not null default 0
); );
create index if not exists claim_id_idx on claim (claim_id);
create index if not exists claim_normalized_idx on claim (normalized); create index if not exists claim_normalized_idx on claim (normalized);
create index if not exists claim_search_idx on claim (normalized, claim_id);
create index if not exists claim_txo_hash_idx on claim (txo_hash); create index if not exists claim_txo_hash_idx on claim (txo_hash);
create index if not exists claim_channel_hash_idx on claim (channel_hash); create index if not exists claim_channel_hash_idx on claim (channel_hash);
create index if not exists claim_release_time_idx on claim (release_time); create index if not exists claim_release_time_idx on claim (release_time);
@ -663,9 +665,11 @@ class SQLDB:
constraints['limit'] = 1 constraints['limit'] = 1
if 'claim_id' in constraints: if 'claim_id' in constraints:
constraints['claim.claim_hash'] = sqlite3.Binary( claim_id = constraints.pop('claim_id')
unhexlify(constraints.pop('claim_id'))[::-1] if len(claim_id) == 40:
) constraints['claim.claim_id'] = claim_id
else:
constraints['claim.claim_id__like'] = f'{claim_id[:40]}%'
if 'name' in constraints: if 'name' in constraints:
constraints['claim.normalized'] = normalize_name(constraints.pop('name')) constraints['claim.normalized'] = normalize_name(constraints.pop('name'))
@ -737,7 +741,7 @@ class SQLDB:
INTEGER_PARAMS = { INTEGER_PARAMS = {
'height', 'creation_height', 'activation_height', 'tx_position', 'height', 'creation_height', 'activation_height', 'tx_position',
'release_time', 'timestamp', 'release_time', 'timestamp', 'is_channel_signature_valid', 'channel_join',
'amount', 'effective_amount', 'support_amount', 'amount', 'effective_amount', 'support_amount',
'trending_group', 'trending_mixed', 'trending_group', 'trending_mixed',
'trending_local', 'trending_global', 'trending_local', 'trending_global',
@ -785,7 +789,9 @@ class SQLDB:
query = url.channel.to_dict() query = url.channel.to_dict()
if set(query) == {'name'}: if set(query) == {'name'}:
query['is_controlling'] = True query['is_controlling'] = True
matches = self._search(**query) else:
query['order_by'] = ['^height']
matches = self._search(**query, limit=1)
if matches: if matches:
channel = matches[0] channel = matches[0]
else: else:
@ -794,10 +800,16 @@ class SQLDB:
if url.has_stream: if url.has_stream:
query = url.stream.to_dict() query = url.stream.to_dict()
if channel is not None: if channel is not None:
if set(query) == {'name'}:
# temporarily emulate is_controlling for claims in channel
query['order_by'] = ['effective_amount']
else:
query['order_by'] = ['^channel_join']
query['channel_hash'] = channel['claim_hash'] query['channel_hash'] = channel['claim_hash']
if set(query) == {'name'}: query['is_channel_signature_valid'] = 1
elif set(query) == {'name'}:
query['is_controlling'] = True query['is_controlling'] = True
matches = self._search(**query) matches = self._search(**query, limit=1)
if matches: if matches:
result.append(matches[0]) result.append(matches[0])
if matches[0]['channel_hash']: if matches[0]['channel_hash']:

View file

@ -126,6 +126,46 @@ class ResolveCommand(CommandTestCase):
await self.assertResolvesToClaimId('foo$3', claim_id1) await self.assertResolvesToClaimId('foo$3', claim_id1)
await self.assertResolvesToClaimId('foo$4', None) await self.assertResolvesToClaimId('foo$4', None)
async def test_partial_claim_id_resolve(self):
# add some noise
await self.channel_create('@abc', '0.1', allow_duplicate_name=True)
await self.channel_create('@abc', '0.2', allow_duplicate_name=True)
await self.channel_create('@abc', '1.0', allow_duplicate_name=True)
channel_id = self.get_claim_id(
await self.channel_create('@abc', '1.1', allow_duplicate_name=True))
await self.assertResolvesToClaimId(f'@abc', channel_id)
await self.assertResolvesToClaimId(f'@abc#{channel_id[0]}', channel_id)
await self.assertResolvesToClaimId(f'@abc#{channel_id[:10]}', channel_id)
await self.assertResolvesToClaimId(f'@abc#{channel_id}', channel_id)
channel = (await self.claim_search(claim_id=channel_id))[0]
await self.assertResolvesToClaimId(channel['short_url'], channel_id)
await self.assertResolvesToClaimId(channel['canonical_url'], channel_id)
await self.assertResolvesToClaimId(channel['permanent_url'], channel_id)
# add some noise
await self.stream_create('foo', '0.1', allow_duplicate_name=True, channel_id=channel['claim_id'])
await self.stream_create('foo', '0.2', allow_duplicate_name=True, channel_id=channel['claim_id'])
await self.stream_create('foo', '0.3', allow_duplicate_name=True, channel_id=channel['claim_id'])
claim_id1 = self.get_claim_id(
await self.stream_create('foo', '0.7', allow_duplicate_name=True, channel_id=channel['claim_id']))
claim1 = (await self.claim_search(claim_id=claim_id1))[0]
await self.assertResolvesToClaimId('foo', claim_id1)
await self.assertResolvesToClaimId('@abc/foo', claim_id1)
await self.assertResolvesToClaimId(claim1['short_url'], claim_id1)
await self.assertResolvesToClaimId(claim1['canonical_url'], claim_id1)
await self.assertResolvesToClaimId(claim1['permanent_url'], claim_id1)
claim_id2 = self.get_claim_id(
await self.stream_create('foo', '0.8', allow_duplicate_name=True, channel_id=channel['claim_id']))
claim2 = (await self.claim_search(claim_id=claim_id2))[0]
await self.assertResolvesToClaimId('foo', claim_id2)
await self.assertResolvesToClaimId('@abc/foo', claim_id2)
await self.assertResolvesToClaimId(claim2['short_url'], claim_id2)
await self.assertResolvesToClaimId(claim2['canonical_url'], claim_id2)
await self.assertResolvesToClaimId(claim2['permanent_url'], claim_id2)
async def test_abandoned_channel_with_signed_claims(self): async def test_abandoned_channel_with_signed_claims(self):
channel = (await self.channel_create('@abc', '1.0'))['outputs'][0] channel = (await self.channel_create('@abc', '1.0'))['outputs'][0]
orphan_claim = await self.stream_create('on-channel-claim', '0.0001', channel_id=channel['claim_id']) orphan_claim = await self.stream_create('on-channel-claim', '0.0001', channel_id=channel['claim_id'])