2020-06-05 06:35:22 +02:00
|
|
|
# pylint: disable=singleton-comparison
|
|
|
|
from sqlalchemy.future import select
|
|
|
|
|
2020-06-19 20:28:34 +02:00
|
|
|
from lbry.db.constants import CLAIM_TYPE_CODES, TXO_TYPES
|
|
|
|
from lbry.db.queries import select_txos, rows_to_txos
|
|
|
|
from lbry.db.query_context import progress, Event
|
|
|
|
from lbry.db.tables import (
|
|
|
|
TXO, TXI, Claim, Support
|
2020-06-05 06:35:22 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
|
2020-06-19 20:28:34 +02:00
|
|
|
def process_all_things_after_sync():
|
2020-06-26 16:39:16 +02:00
|
|
|
with progress(Event.INPUT_UPDATE) as p:
|
|
|
|
p.start(2)
|
|
|
|
set_input_addresses(p.ctx)
|
|
|
|
p.step(1)
|
|
|
|
update_spent_outputs(p.ctx)
|
|
|
|
p.step(2)
|
|
|
|
with progress(Event.SUPPORT_DELETE) as p:
|
|
|
|
p.start(1)
|
|
|
|
sql = Support.delete().where(condition_spent_supports)
|
|
|
|
p.ctx.execute(sql)
|
|
|
|
with progress(Event.SUPPORT_INSERT) as p:
|
|
|
|
loader = p.ctx.get_bulk_loader()
|
|
|
|
for support in rows_to_txos(p.ctx.fetchall(select_missing_supports)):
|
|
|
|
loader.add_support(support)
|
|
|
|
loader.save()
|
|
|
|
with progress(Event.CLAIM_DELETE) as p:
|
|
|
|
p.start(1)
|
|
|
|
sql = Claim.delete().where(condition_spent_claims())
|
|
|
|
p.ctx.execute(sql)
|
|
|
|
with progress(Event.CLAIM_INSERT) as p:
|
|
|
|
loader = p.ctx.get_bulk_loader()
|
|
|
|
for claim in rows_to_txos(p.ctx.fetchall(select_missing_claims)):
|
|
|
|
loader.add_claim(claim)
|
|
|
|
loader.save()
|
|
|
|
with progress(Event.CLAIM_UPDATE) as p:
|
|
|
|
loader = p.ctx.get_bulk_loader()
|
|
|
|
for claim in rows_to_txos(p.ctx.fetchall(select_stale_claims)):
|
|
|
|
loader.update_claim(claim)
|
|
|
|
loader.save()
|
2020-06-19 20:28:34 +02:00
|
|
|
|
|
|
|
|
2020-06-26 16:39:16 +02:00
|
|
|
def set_input_addresses(ctx):
|
|
|
|
# Update TXIs to have the address of TXO they are spending.
|
|
|
|
if ctx.is_sqlite:
|
|
|
|
address_query = select(TXO.c.address).where(TXI.c.txo_hash == TXO.c.txo_hash)
|
|
|
|
set_addresses = (
|
|
|
|
TXI.update()
|
|
|
|
.values(address=address_query.scalar_subquery())
|
|
|
|
.where(TXI.c.address == None)
|
|
|
|
)
|
|
|
|
else:
|
|
|
|
set_addresses = (
|
|
|
|
TXI.update()
|
|
|
|
.values({TXI.c.address: TXO.c.address})
|
|
|
|
.where((TXI.c.address == None) & (TXI.c.txo_hash == TXO.c.txo_hash))
|
|
|
|
)
|
2020-06-19 20:28:34 +02:00
|
|
|
|
2020-06-26 16:39:16 +02:00
|
|
|
ctx.execute(set_addresses)
|
2020-06-19 20:28:34 +02:00
|
|
|
|
|
|
|
|
2020-06-26 16:39:16 +02:00
|
|
|
def update_spent_outputs(ctx):
|
2020-07-06 05:03:45 +02:00
|
|
|
# Update spent TXOs setting spent_height
|
|
|
|
set_spent_height = (
|
2020-06-26 16:39:16 +02:00
|
|
|
TXO.update()
|
2020-07-06 05:03:45 +02:00
|
|
|
.values({
|
|
|
|
TXO.c.spent_height: (
|
|
|
|
select(TXI.c.height)
|
|
|
|
.where(TXI.c.txo_hash == TXO.c.txo_hash)
|
2020-07-07 04:42:15 +02:00
|
|
|
.scalar_subquery()
|
2020-07-06 05:03:45 +02:00
|
|
|
)
|
|
|
|
}).where(
|
|
|
|
(TXO.c.spent_height == 0) &
|
2020-06-26 16:39:16 +02:00
|
|
|
(TXO.c.txo_hash.in_(select(TXI.c.txo_hash)))
|
2020-06-19 20:28:34 +02:00
|
|
|
)
|
2020-06-26 16:39:16 +02:00
|
|
|
)
|
2020-07-06 05:03:45 +02:00
|
|
|
ctx.execute(set_spent_height)
|
2020-06-19 20:28:34 +02:00
|
|
|
|
|
|
|
|
|
|
|
def condition_spent_claims(claim_type: list = None):
|
|
|
|
if claim_type is not None:
|
|
|
|
if len(claim_type) == 0:
|
|
|
|
raise ValueError("Missing 'claim_type'.")
|
|
|
|
if len(claim_type) == 1:
|
|
|
|
type_filter = TXO.c.txo_type == claim_type[0]
|
|
|
|
else:
|
|
|
|
type_filter = TXO.c.txo_type.in_(claim_type)
|
|
|
|
else:
|
|
|
|
type_filter = TXO.c.txo_type.in_(CLAIM_TYPE_CODES)
|
|
|
|
return Claim.c.claim_hash.notin_(
|
2020-07-06 05:03:45 +02:00
|
|
|
select(TXO.c.claim_hash).where(type_filter & (TXO.c.spent_height == 0))
|
2020-06-19 20:28:34 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
# find UTXOs that are claims and their claim_id is not in claim table,
|
|
|
|
# this means they need to be inserted
|
|
|
|
select_missing_claims = (
|
2020-07-06 05:03:45 +02:00
|
|
|
select_txos(txo_type__in=CLAIM_TYPE_CODES, spent_height=0, claim_id_not_in_claim_table=True)
|
2020-06-19 20:28:34 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
# find UTXOs that are claims and their txo_id is not in claim table,
|
|
|
|
# this ONLY works if you first ran select_missing_claims and inserted the missing claims, then
|
|
|
|
# all claims_ids should match between TXO and Claim table but txo_hashes will not match for
|
|
|
|
# claims that are not up-to-date
|
|
|
|
select_stale_claims = (
|
2020-07-06 05:03:45 +02:00
|
|
|
select_txos(txo_type__in=CLAIM_TYPE_CODES, spent_height=0, txo_id_not_in_claim_table=True)
|
2020-06-19 20:28:34 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
condition_spent_supports = (
|
|
|
|
Support.c.txo_hash.notin_(
|
|
|
|
select(TXO.c.txo_hash).where(
|
|
|
|
(TXO.c.txo_type == TXO_TYPES['support']) &
|
2020-07-06 05:03:45 +02:00
|
|
|
(TXO.c.spent_height == 0)
|
2020-06-19 20:28:34 +02:00
|
|
|
)
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
|
2020-07-06 05:03:45 +02:00
|
|
|
condition_missing_supports = (
|
|
|
|
(TXO.c.txo_type == TXO_TYPES['support']) &
|
|
|
|
(TXO.c.spent_height == 0) &
|
|
|
|
(TXO.c.txo_hash.notin_(select(Support.c.txo_hash)))
|
|
|
|
)
|
|
|
|
|
|
|
|
|
2020-06-19 20:28:34 +02:00
|
|
|
select_missing_supports = (
|
2020-07-06 05:03:45 +02:00
|
|
|
select_txos(txo_type=TXO_TYPES['support'], spent_height=0, txo_id_not_in_support_table=True)
|
2020-06-19 20:28:34 +02:00
|
|
|
)
|