forked from LBRYCommunity/lbry-sdk
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.ledger import MainNetLedger
|
||||
from lbrynet.stream.stream_manager import StreamManager
|
||||
from lbrynet.stream.managed_stream import ManagedStream
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
@ -1808,9 +1807,9 @@ class Daemon(metaclass=JSONRPCServerType):
|
|||
Returns: {Paginated[Output]}
|
||||
"""
|
||||
if kwargs.pop('valid_channel_signatures', False):
|
||||
kwargs['is_channel_signature_valid'] = 1
|
||||
kwargs['signature_valid'] = 1
|
||||
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)
|
||||
kwargs.update({'offset': page_size * (page_num-1), 'limit': page_size})
|
||||
txos, offset, total = await self.ledger.claim_search(**kwargs)
|
||||
|
|
|
@ -184,12 +184,13 @@ class JSONResponseEncoder(JSONEncoder):
|
|||
output['value_type'] = txo.claim.claim_type
|
||||
if self.include_protobuf:
|
||||
output['protobuf'] = hexlify(txo.claim.to_bytes())
|
||||
if txo.channel is not None:
|
||||
output['signing_channel'] = self.encode_output(txo.channel)
|
||||
if check_signature and txo.claim.is_signed:
|
||||
if check_signature and txo.claim.is_signed:
|
||||
if txo.channel is not None:
|
||||
output['signing_channel'] = self.encode_output(txo.channel)
|
||||
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
|
||||
if txo.channel:
|
||||
output['is_channel_signature_valid'] = txo.is_signed_by(txo.channel, self.ledger)
|
||||
except DecodeError:
|
||||
pass
|
||||
return output
|
||||
|
|
|
@ -195,14 +195,13 @@ class Stream(BaseClaim):
|
|||
claim['source']['hash'] = self.source.file_hash
|
||||
if 'sd_hash' in claim['source']:
|
||||
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', {})
|
||||
if 'address' in fee:
|
||||
fee['address'] = self.fee.address
|
||||
if 'amount' in fee:
|
||||
fee['amount'] = str(self.fee.amount)
|
||||
stream_type = self.message.WhichOneof('type')
|
||||
if stream_type:
|
||||
claim['stream_type'] = stream_type
|
||||
return claim
|
||||
|
||||
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
|
||||
signature bytes,
|
||||
signature_digest bytes,
|
||||
is_channel_signature_valid bool not null default false,
|
||||
signature_valid bool,
|
||||
|
||||
effective_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_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_trending_group_idx on claim (trending_group);
|
||||
create index if not exists claim_trending_mixed_idx on claim (trending_mixed);
|
||||
|
@ -431,13 +433,14 @@ class SQLDB:
|
|||
'channel_hash': None,
|
||||
'signature': None,
|
||||
'signature_digest': None,
|
||||
'is_channel_signature_valid': False
|
||||
'signature_valid': None
|
||||
}
|
||||
if claim.is_signed:
|
||||
update.update({
|
||||
'channel_hash': sqlite3.Binary(claim.signing_channel_hash),
|
||||
'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)
|
||||
|
||||
|
@ -454,13 +457,13 @@ class SQLDB:
|
|||
'channel_hash': sqlite3.Binary(affected_claim['channel_hash']),
|
||||
'signature': sqlite3.Binary(affected_claim['signature']),
|
||||
'signature_digest': sqlite3.Binary(affected_claim['signature_digest']),
|
||||
'is_channel_signature_valid': False
|
||||
'signature_valid': 0
|
||||
})
|
||||
|
||||
for update in claim_updates:
|
||||
channel_pub_key = all_channel_keys.get(update['channel_hash'])
|
||||
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
|
||||
)
|
||||
|
||||
|
@ -468,20 +471,20 @@ class SQLDB:
|
|||
self.db.executemany(f"""
|
||||
UPDATE claim SET
|
||||
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
|
||||
WHEN is_channel_signature_valid AND :is_channel_signature_valid THEN channel_join
|
||||
WHEN :is_channel_signature_valid THEN {height}
|
||||
WHEN signature_valid=1 AND :signature_valid=1 THEN channel_join
|
||||
WHEN :signature_valid=1 THEN {height}
|
||||
END,
|
||||
canonical_url=CASE
|
||||
WHEN is_channel_signature_valid AND :is_channel_signature_valid THEN canonical_url
|
||||
WHEN :is_channel_signature_valid THEN
|
||||
WHEN signature_valid=1 AND :signature_valid=1 THEN canonical_url
|
||||
WHEN :signature_valid=1 THEN
|
||||
(SELECT short_url FROM claim WHERE claim_hash=:channel_hash)||'/'||
|
||||
claim_name||COALESCE(
|
||||
(SELECT shortest_id(other_claim.claim_id, claim.claim_id) FROM claim AS other_claim
|
||||
WHERE other_claim.normalized = claim.normalized 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)
|
||||
)
|
||||
END
|
||||
|
@ -491,7 +494,9 @@ class SQLDB:
|
|||
if spent_claims:
|
||||
self.execute(
|
||||
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)})
|
||||
""", [sqlite3.Binary(cid) for cid in spent_claims]
|
||||
)
|
||||
|
@ -517,7 +522,7 @@ class SQLDB:
|
|||
claims_in_channel=(
|
||||
SELECT COUNT(*) FROM claim AS claim_in_channel
|
||||
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 = ?
|
||||
""", [(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.short_url, claim.canonical_url,
|
||||
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
|
||||
)
|
||||
|
||||
INTEGER_PARAMS = {
|
||||
'height', 'creation_height', 'activation_height', 'expiration_height',
|
||||
'timestamp', 'creation_timestamp', 'release_time',
|
||||
'tx_position', 'channel_join', 'is_channel_signature_valid',
|
||||
'tx_position', 'channel_join', 'signature_valid',
|
||||
'amount', 'effective_amount', 'support_amount',
|
||||
'trending_group', 'trending_mixed',
|
||||
'trending_local', 'trending_global',
|
||||
|
@ -870,7 +875,7 @@ class SQLDB:
|
|||
else:
|
||||
query['order_by'] = ['^channel_join']
|
||||
query['channel_hash'] = channel['claim_hash']
|
||||
query['is_channel_signature_valid'] = 1
|
||||
query['signature_valid'] = 1
|
||||
elif set(query) == {'name'}:
|
||||
query['is_controlling'] = 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
|
||||
await self.assertFindsClaims([signed2], channel_ids=[channel_id2, self.channel_id],
|
||||
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
|
||||
await self.stream_abandon(txid=signed2['txid'], nout=0)
|
||||
|
|
Loading…
Reference in a new issue