fix bug with resolve and conflicting claim_id segments

This commit is contained in:
Lex Berezhny 2019-10-23 10:54:05 -04:00
parent a7f8febed7
commit bb8a2bfff7
3 changed files with 12 additions and 53 deletions

View file

@ -397,7 +397,7 @@ def resolve_url(raw_url):
if set(query) == {'name'}:
query['is_controlling'] = True
else:
query['order_by'] = ['^height']
query['order_by'] = ['^creation_height']
matches = _search(**query, limit=1)
if matches:
channel = matches[0]

View file

@ -259,58 +259,6 @@ class ResolveCommand(BaseResolveTestCase):
'@olds/bad_example': {'error': '@olds/bad_example did not resolve to a claim'}
})
async def _test_resolve_abc_foo(self):
response = await self.resolve('lbry://@abc/foo')
claim = response['lbry://@abc/foo']
self.assertIn('signing_channel', claim)
self.assertEqual(claim['name'], 'foo')
self.assertEqual(claim['signing_channel']['name'], '@abc')
self.assertEqual(claim['meta']['claims_in_channel'], 0)
self.assertEqual(
claim['timestamp'],
self.ledger.headers[claim['height']]['timestamp']
)
self.assertEqual(
claim['signing_channel']['timestamp'],
self.ledger.headers[claim['signing_channel']['height']]['timestamp']
)
@skip('this test does not work with new resolve')
async def test_resolve_lru_cache_doesnt_persist_errors(self):
original_get_transaction = self.daemon.wallet_manager.ledger.network.get_transaction
async def timeout_get_transaction(txid):
fut = self.loop.create_future()
def delayed_raise_cancelled_error():
fut.set_exception(asyncio.CancelledError())
self.loop.call_soon(delayed_raise_cancelled_error)
return await fut
tx = await self.channel_create('@abc', '0.01')
channel_id = self.get_claim_id(tx)
await self.stream_create('foo', '0.01', channel_id=channel_id)
# raise a cancelled error from get_transaction
self.daemon.wallet_manager.ledger.network.get_transaction = timeout_get_transaction
with self.assertRaises(KeyError):
await self._test_resolve_abc_foo()
# restore the real get_transaction that doesn't cancel, it should be called and the result cached
self.daemon.wallet_manager.ledger.network.get_transaction = original_get_transaction
await self._test_resolve_abc_foo()
called_again = asyncio.Event(loop=self.loop)
def check_result_cached(txid):
called_again.set()
return original_get_transaction(txid)
# check that the result was cached
self.daemon.wallet_manager.ledger.network.get_transaction = check_result_cached
await self._test_resolve_abc_foo()
self.assertFalse(called_again.is_set())
class ResolveAfterReorg(BaseResolveTestCase):

View file

@ -343,6 +343,7 @@ class TestClaimtrie(TestSQLDB):
tx_chan_a = self.get_channel_with_claim_id_prefix('a', 1, key=b'c')
tx_chan_ab = self.get_channel_with_claim_id_prefix('ab', 72, key=b'c')
txo_chan_a = tx_chan_a[0].tx.outputs[0]
txo_chan_ab = tx_chan_ab[0].tx.outputs[0]
advance(1, [tx_chan_a])
advance(2, [tx_chan_ab])
r_ab, r_a = reader._search(order_by=['creation_height'], limit=2)
@ -379,6 +380,12 @@ class TestClaimtrie(TestSQLDB):
self.assertEqual("@foo#a/foo#ab", r_ab2['canonical_url'])
self.assertEqual(2, reader._search(claim_id=txo_chan_a.claim_id, limit=1)[0]['claims_in_channel'])
# pick correct claim in case of claims with conflicting claim id segments
# make sure that activation_height is used instead of height (issue #2448)
# after updating chan "a" check this again
self.assertEqual(reader.resolve_url("@foo#a")['claim_hash'], txo_chan_a.claim_hash)
self.assertEqual(reader.resolve_url("@foo#ab")['claim_hash'], txo_chan_ab.claim_hash)
# change channel public key, invaliding stream claim signatures
advance(8, [self.get_channel_update(txo_chan_a, COIN, key=b'a')])
r_ab2, r_a2 = reader._search(order_by=['creation_height'], limit=2)
@ -398,6 +405,10 @@ class TestClaimtrie(TestSQLDB):
self.assertEqual("@foo#a/foo#ab", r_ab2['canonical_url'])
self.assertEqual(2, reader._search(claim_id=txo_chan_a.claim_id, limit=1)[0]['claims_in_channel'])
# check chan "a" is still resolved (issue #2448)
self.assertEqual(reader.resolve_url("@foo#a")['claim_hash'], txo_chan_a.claim_hash)
self.assertEqual(reader.resolve_url("@foo#ab")['claim_hash'], txo_chan_ab.claim_hash)
# claim abandon updates claims_in_channel
advance(10, [self.get_abandon(tx_ab2)])
self.assertEqual(1, reader._search(claim_id=txo_chan_a.claim_id, limit=1)[0]['claims_in_channel'])