better handling for claims in abandoned channels
This commit is contained in:
parent
f96c46e84a
commit
f23aea9951
5 changed files with 42 additions and 27 deletions
|
@ -51,7 +51,6 @@ if typing.TYPE_CHECKING:
|
||||||
from lbrynet.wallet.manager import LbryWalletManager
|
from lbrynet.wallet.manager import LbryWalletManager
|
||||||
from lbrynet.wallet.ledger import MainNetLedger
|
from lbrynet.wallet.ledger import MainNetLedger
|
||||||
from lbrynet.stream.stream_manager import StreamManager
|
from lbrynet.stream.stream_manager import StreamManager
|
||||||
from lbrynet.stream.managed_stream import ManagedStream
|
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -1808,9 +1807,9 @@ class Daemon(metaclass=JSONRPCServerType):
|
||||||
Returns: {Paginated[Output]}
|
Returns: {Paginated[Output]}
|
||||||
"""
|
"""
|
||||||
if kwargs.pop('valid_channel_signatures', False):
|
if kwargs.pop('valid_channel_signatures', False):
|
||||||
kwargs['is_channel_signature_valid'] = 1
|
kwargs['signature_valid'] = 1
|
||||||
if kwargs.pop('invalid_channel_signatures', False):
|
if kwargs.pop('invalid_channel_signatures', False):
|
||||||
kwargs['is_channel_signature_valid'] = 0
|
kwargs['signature_valid'] = 0
|
||||||
page_num, page_size = abs(kwargs.pop('page', 1)), min(abs(kwargs.pop('page_size', 10)), 50)
|
page_num, page_size = abs(kwargs.pop('page', 1)), min(abs(kwargs.pop('page_size', 10)), 50)
|
||||||
kwargs.update({'offset': page_size * (page_num-1), 'limit': page_size})
|
kwargs.update({'offset': page_size * (page_num-1), 'limit': page_size})
|
||||||
txos, offset, total = await self.ledger.claim_search(**kwargs)
|
txos, offset, total = await self.ledger.claim_search(**kwargs)
|
||||||
|
|
|
@ -184,12 +184,13 @@ class JSONResponseEncoder(JSONEncoder):
|
||||||
output['value_type'] = txo.claim.claim_type
|
output['value_type'] = txo.claim.claim_type
|
||||||
if self.include_protobuf:
|
if self.include_protobuf:
|
||||||
output['protobuf'] = hexlify(txo.claim.to_bytes())
|
output['protobuf'] = hexlify(txo.claim.to_bytes())
|
||||||
|
if check_signature and txo.claim.is_signed:
|
||||||
if txo.channel is not None:
|
if txo.channel is not None:
|
||||||
output['signing_channel'] = self.encode_output(txo.channel)
|
output['signing_channel'] = self.encode_output(txo.channel)
|
||||||
if check_signature and txo.claim.is_signed:
|
|
||||||
output['is_channel_signature_valid'] = False
|
|
||||||
if txo.channel:
|
|
||||||
output['is_channel_signature_valid'] = txo.is_signed_by(txo.channel, self.ledger)
|
output['is_channel_signature_valid'] = txo.is_signed_by(txo.channel, self.ledger)
|
||||||
|
else:
|
||||||
|
output['signing_channel'] = {'channel_id': txo.claim.signing_channel_id}
|
||||||
|
output['is_channel_signature_valid'] = False
|
||||||
except DecodeError:
|
except DecodeError:
|
||||||
pass
|
pass
|
||||||
return output
|
return output
|
||||||
|
|
|
@ -195,14 +195,13 @@ class Stream(BaseClaim):
|
||||||
claim['source']['hash'] = self.source.file_hash
|
claim['source']['hash'] = self.source.file_hash
|
||||||
if 'sd_hash' in claim['source']:
|
if 'sd_hash' in claim['source']:
|
||||||
claim['source']['sd_hash'] = self.source.sd_hash
|
claim['source']['sd_hash'] = self.source.sd_hash
|
||||||
|
if 'media_type' in claim['source']:
|
||||||
|
claim['stream_type'] = guess_stream_type(claim['source']['media_type'])
|
||||||
fee = claim.get('fee', {})
|
fee = claim.get('fee', {})
|
||||||
if 'address' in fee:
|
if 'address' in fee:
|
||||||
fee['address'] = self.fee.address
|
fee['address'] = self.fee.address
|
||||||
if 'amount' in fee:
|
if 'amount' in fee:
|
||||||
fee['amount'] = str(self.fee.amount)
|
fee['amount'] = str(self.fee.amount)
|
||||||
stream_type = self.message.WhichOneof('type')
|
|
||||||
if stream_type:
|
|
||||||
claim['stream_type'] = stream_type
|
|
||||||
return claim
|
return claim
|
||||||
|
|
||||||
def update(self, file_path=None, height=None, width=None, duration=None, **kwargs):
|
def update(self, file_path=None, height=None, width=None, duration=None, **kwargs):
|
||||||
|
|
|
@ -116,7 +116,7 @@ class SQLDB:
|
||||||
channel_join integer, -- height at which claim got valid signature / joined channel
|
channel_join integer, -- height at which claim got valid signature / joined channel
|
||||||
signature bytes,
|
signature bytes,
|
||||||
signature_digest bytes,
|
signature_digest bytes,
|
||||||
is_channel_signature_valid bool not null default false,
|
signature_valid bool,
|
||||||
|
|
||||||
effective_amount integer not null default 0,
|
effective_amount integer not null default 0,
|
||||||
support_amount integer not null default 0,
|
support_amount integer not null default 0,
|
||||||
|
@ -141,6 +141,8 @@ class SQLDB:
|
||||||
create index if not exists claim_stream_type_idx on claim (stream_type);
|
create index if not exists claim_stream_type_idx on claim (stream_type);
|
||||||
create index if not exists claim_media_type_idx on claim (media_type);
|
create index if not exists claim_media_type_idx on claim (media_type);
|
||||||
|
|
||||||
|
create index if not exists claim_signature_valid_idx on claim (signature_valid);
|
||||||
|
|
||||||
create index if not exists claim_effective_amount_idx on claim (effective_amount);
|
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);
|
create index if not exists claim_trending_group_idx on claim (trending_group);
|
||||||
create index if not exists claim_trending_mixed_idx on claim (trending_mixed);
|
create index if not exists claim_trending_mixed_idx on claim (trending_mixed);
|
||||||
|
@ -431,13 +433,14 @@ class SQLDB:
|
||||||
'channel_hash': None,
|
'channel_hash': None,
|
||||||
'signature': None,
|
'signature': None,
|
||||||
'signature_digest': None,
|
'signature_digest': None,
|
||||||
'is_channel_signature_valid': False
|
'signature_valid': None
|
||||||
}
|
}
|
||||||
if claim.is_signed:
|
if claim.is_signed:
|
||||||
update.update({
|
update.update({
|
||||||
'channel_hash': sqlite3.Binary(claim.signing_channel_hash),
|
'channel_hash': sqlite3.Binary(claim.signing_channel_hash),
|
||||||
'signature': sqlite3.Binary(txo.get_encoded_signature()),
|
'signature': sqlite3.Binary(txo.get_encoded_signature()),
|
||||||
'signature_digest': sqlite3.Binary(txo.get_signature_digest(self.ledger))
|
'signature_digest': sqlite3.Binary(txo.get_signature_digest(self.ledger)),
|
||||||
|
'signature_valid': 0
|
||||||
})
|
})
|
||||||
claim_updates.append(update)
|
claim_updates.append(update)
|
||||||
|
|
||||||
|
@ -454,13 +457,13 @@ class SQLDB:
|
||||||
'channel_hash': sqlite3.Binary(affected_claim['channel_hash']),
|
'channel_hash': sqlite3.Binary(affected_claim['channel_hash']),
|
||||||
'signature': sqlite3.Binary(affected_claim['signature']),
|
'signature': sqlite3.Binary(affected_claim['signature']),
|
||||||
'signature_digest': sqlite3.Binary(affected_claim['signature_digest']),
|
'signature_digest': sqlite3.Binary(affected_claim['signature_digest']),
|
||||||
'is_channel_signature_valid': False
|
'signature_valid': 0
|
||||||
})
|
})
|
||||||
|
|
||||||
for update in claim_updates:
|
for update in claim_updates:
|
||||||
channel_pub_key = all_channel_keys.get(update['channel_hash'])
|
channel_pub_key = all_channel_keys.get(update['channel_hash'])
|
||||||
if channel_pub_key and update['signature']:
|
if channel_pub_key and update['signature']:
|
||||||
update['is_channel_signature_valid'] = Output.is_signature_valid(
|
update['signature_valid'] = Output.is_signature_valid(
|
||||||
bytes(update['signature']), bytes(update['signature_digest']), channel_pub_key
|
bytes(update['signature']), bytes(update['signature_digest']), channel_pub_key
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -468,20 +471,20 @@ class SQLDB:
|
||||||
self.db.executemany(f"""
|
self.db.executemany(f"""
|
||||||
UPDATE claim SET
|
UPDATE claim SET
|
||||||
channel_hash=:channel_hash, signature=:signature, signature_digest=:signature_digest,
|
channel_hash=:channel_hash, signature=:signature, signature_digest=:signature_digest,
|
||||||
is_channel_signature_valid=:is_channel_signature_valid,
|
signature_valid=:signature_valid,
|
||||||
channel_join=CASE
|
channel_join=CASE
|
||||||
WHEN is_channel_signature_valid AND :is_channel_signature_valid THEN channel_join
|
WHEN signature_valid=1 AND :signature_valid=1 THEN channel_join
|
||||||
WHEN :is_channel_signature_valid THEN {height}
|
WHEN :signature_valid=1 THEN {height}
|
||||||
END,
|
END,
|
||||||
canonical_url=CASE
|
canonical_url=CASE
|
||||||
WHEN is_channel_signature_valid AND :is_channel_signature_valid THEN canonical_url
|
WHEN signature_valid=1 AND :signature_valid=1 THEN canonical_url
|
||||||
WHEN :is_channel_signature_valid THEN
|
WHEN :signature_valid=1 THEN
|
||||||
(SELECT short_url FROM claim WHERE claim_hash=:channel_hash)||'/'||
|
(SELECT short_url FROM claim WHERE claim_hash=:channel_hash)||'/'||
|
||||||
claim_name||COALESCE(
|
claim_name||COALESCE(
|
||||||
(SELECT shortest_id(other_claim.claim_id, claim.claim_id) FROM claim AS other_claim
|
(SELECT shortest_id(other_claim.claim_id, claim.claim_id) FROM claim AS other_claim
|
||||||
WHERE other_claim.normalized = claim.normalized AND
|
WHERE other_claim.normalized = claim.normalized AND
|
||||||
other_claim.channel_hash = :channel_hash AND
|
other_claim.channel_hash = :channel_hash AND
|
||||||
other_claim.is_channel_signature_valid = 1),
|
other_claim.signature_valid = 1),
|
||||||
'#'||substr(claim_id, 1, 1)
|
'#'||substr(claim_id, 1, 1)
|
||||||
)
|
)
|
||||||
END
|
END
|
||||||
|
@ -491,7 +494,9 @@ class SQLDB:
|
||||||
if spent_claims:
|
if spent_claims:
|
||||||
self.execute(
|
self.execute(
|
||||||
f"""
|
f"""
|
||||||
UPDATE claim SET is_channel_signature_valid=0, channel_join=NULL, canonical_url=NULL
|
UPDATE claim SET
|
||||||
|
signature_valid=CASE WHEN signature IS NOT NULL THEN 0 END,
|
||||||
|
channel_join=NULL, canonical_url=NULL
|
||||||
WHERE channel_hash IN ({','.join('?' for _ in spent_claims)})
|
WHERE channel_hash IN ({','.join('?' for _ in spent_claims)})
|
||||||
""", [sqlite3.Binary(cid) for cid in spent_claims]
|
""", [sqlite3.Binary(cid) for cid in spent_claims]
|
||||||
)
|
)
|
||||||
|
@ -517,7 +522,7 @@ class SQLDB:
|
||||||
claims_in_channel=(
|
claims_in_channel=(
|
||||||
SELECT COUNT(*) FROM claim AS claim_in_channel
|
SELECT COUNT(*) FROM claim AS claim_in_channel
|
||||||
WHERE claim_in_channel.channel_hash=claim.claim_hash AND
|
WHERE claim_in_channel.channel_hash=claim.claim_hash AND
|
||||||
claim_in_channel.is_channel_signature_valid
|
claim_in_channel.signature_valid=1
|
||||||
)
|
)
|
||||||
WHERE claim_hash = ?
|
WHERE claim_hash = ?
|
||||||
""", [(sqlite3.Binary(channel_hash),) for channel_hash in all_channel_keys.keys()])
|
""", [(sqlite3.Binary(channel_hash),) for channel_hash in all_channel_keys.keys()])
|
||||||
|
@ -800,14 +805,14 @@ class SQLDB:
|
||||||
claim.trending_local, claim.trending_global,
|
claim.trending_local, claim.trending_global,
|
||||||
claim.short_url, claim.canonical_url,
|
claim.short_url, claim.canonical_url,
|
||||||
claim.channel_hash, channel.txo_hash AS channel_txo_hash,
|
claim.channel_hash, channel.txo_hash AS channel_txo_hash,
|
||||||
channel.height AS channel_height, claim.is_channel_signature_valid
|
channel.height AS channel_height, claim.signature_valid
|
||||||
""", **constraints
|
""", **constraints
|
||||||
)
|
)
|
||||||
|
|
||||||
INTEGER_PARAMS = {
|
INTEGER_PARAMS = {
|
||||||
'height', 'creation_height', 'activation_height', 'expiration_height',
|
'height', 'creation_height', 'activation_height', 'expiration_height',
|
||||||
'timestamp', 'creation_timestamp', 'release_time',
|
'timestamp', 'creation_timestamp', 'release_time',
|
||||||
'tx_position', 'channel_join', 'is_channel_signature_valid',
|
'tx_position', 'channel_join', 'signature_valid',
|
||||||
'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',
|
||||||
|
@ -870,7 +875,7 @@ class SQLDB:
|
||||||
else:
|
else:
|
||||||
query['order_by'] = ['^channel_join']
|
query['order_by'] = ['^channel_join']
|
||||||
query['channel_hash'] = channel['claim_hash']
|
query['channel_hash'] = channel['claim_hash']
|
||||||
query['is_channel_signature_valid'] = 1
|
query['signature_valid'] = 1
|
||||||
elif set(query) == {'name'}:
|
elif set(query) == {'name'}:
|
||||||
query['is_controlling'] = 1
|
query['is_controlling'] = 1
|
||||||
matches = self._search(**query, limit=1)
|
matches = self._search(**query, limit=1)
|
||||||
|
|
|
@ -144,6 +144,17 @@ class ClaimSearchCommand(ClaimTestCase):
|
||||||
# pass `invalid_channel_signatures=False` to catch a bug in argument processing
|
# pass `invalid_channel_signatures=False` to catch a bug in argument processing
|
||||||
await self.assertFindsClaims([signed2], channel_ids=[channel_id2, self.channel_id],
|
await self.assertFindsClaims([signed2], channel_ids=[channel_id2, self.channel_id],
|
||||||
valid_channel_signatures=True, invalid_channel_signatures=False)
|
valid_channel_signatures=True, invalid_channel_signatures=False)
|
||||||
|
# invalid signature still returns channel_id
|
||||||
|
self.ledger._tx_cache.clear()
|
||||||
|
invalid_claims = await self.claim_search(invalid_channel_signatures=True)
|
||||||
|
self.assertEqual(3, len(invalid_claims))
|
||||||
|
self.assertTrue(all([not c['is_channel_signature_valid'] for c in invalid_claims]))
|
||||||
|
self.assertEqual({'channel_id': self.channel_id}, invalid_claims[0]['signing_channel'])
|
||||||
|
|
||||||
|
valid_claims = await self.claim_search(valid_channel_signatures=True)
|
||||||
|
self.assertEqual(1, len(valid_claims))
|
||||||
|
self.assertTrue(all([c['is_channel_signature_valid'] for c in valid_claims]))
|
||||||
|
self.assertEqual('@abc', valid_claims[0]['signing_channel']['name'])
|
||||||
|
|
||||||
# abandoned stream won't show up for streams in channel search
|
# abandoned stream won't show up for streams in channel search
|
||||||
await self.stream_abandon(txid=signed2['txid'], nout=0)
|
await self.stream_abandon(txid=signed2['txid'], nout=0)
|
||||||
|
|
Loading…
Reference in a new issue