diff --git a/lbry/wallet/server/block_processor.py b/lbry/wallet/server/block_processor.py index d155e5348..2d04f1ecd 100644 --- a/lbry/wallet/server/block_processor.py +++ b/lbry/wallet/server/block_processor.py @@ -530,7 +530,7 @@ class BlockProcessor: # print(f"\tupdate {claim_hash.hex()} {tx_hash[::-1].hex()} {txo.amount}") if (prev_tx_num, prev_idx) in self.pending_claims: previous_claim = self.pending_claims.pop((prev_tx_num, prev_idx)) - root_tx_num, root_idx = previous_claim.root_claim_tx_num, previous_claim.root_claim_tx_position + root_tx_num, root_idx = previous_claim.root_tx_num, previous_claim.root_position else: v = self.db.get_claim_txo( claim_hash @@ -638,7 +638,7 @@ class BlockProcessor: if (tx_num, nout) in self.pending_claims: pending = self.pending_claims.pop((tx_num, nout)) self.staged_pending_abandoned[pending.claim_hash] = pending - claim_root_tx_num, claim_root_idx = pending.root_claim_tx_num, pending.root_claim_tx_position + claim_root_tx_num, claim_root_idx = pending.root_tx_num, pending.root_position prev_amount, prev_signing_hash = pending.amount, pending.signing_hash reposted_claim_hash = pending.reposted_claim_hash expiration = self.coin.get_expiration_height(self.height) @@ -672,8 +672,8 @@ class BlockProcessor: if claim_hash in self.staged_pending_abandoned: continue self.signatures_changed.add(claim_hash) - if claim_hash in self.pending_claims: - claim = self.pending_claims[claim_hash] + if claim_hash in self.pending_claim_txos: + claim = self.pending_claims[self.pending_claim_txos[claim_hash]] else: claim = self.db.get_claim_txo(claim_hash) assert claim is not None @@ -1131,32 +1131,35 @@ class BlockProcessor: # use the cumulative changes to update bid ordered resolve for removed in self.removed_claims_to_send_es: removed_claim = self.db.get_claim_txo(removed) - if not removed_claim: - continue - amt = self._cached_get_effective_amount(removed) - if amt <= 0: - continue - ops.extend(get_remove_effective_amount_ops( - removed_claim.name, amt, removed_claim.tx_num, - removed_claim.position, removed - )) + if removed_claim: + amt = self.db.get_url_effective_amount( + removed_claim.name, removed_claim.tx_num, removed_claim.position, removed + ) + if amt and amt > 0: + self.claimtrie_stash.extend(get_remove_effective_amount_ops( + removed_claim.name, amt, removed_claim.tx_num, + removed_claim.position, removed + )) for touched in self.touched_claims_to_send_es: if touched in self.pending_claim_txos: pending = self.pending_claims[self.pending_claim_txos[touched]] name, tx_num, position = pending.name, pending.tx_num, pending.position claim_from_db = self.db.get_claim_txo(touched) if claim_from_db: - amount = self._cached_get_effective_amount(touched) - if amount > 0: - prev_tx_num, prev_position = claim_from_db.tx_num, claim_from_db.position + amount = self.db.get_url_effective_amount( + name, claim_from_db.tx_num, claim_from_db.position, touched + ) + if amount and amount > 0: self.claimtrie_stash.extend(get_remove_effective_amount_ops( - name, amount, prev_tx_num, prev_position, touched + name, amount, claim_from_db.tx_num, claim_from_db.position, touched )) else: v = self.db.get_claim_txo(touched) + if not v: + continue name, tx_num, position = v.name, v.tx_num, v.position - amt = self._cached_get_effective_amount(touched) - if amt > 0: + amt = self.db.get_url_effective_amount(name, tx_num, position, touched) + if amt and amt > 0: self.claimtrie_stash.extend(get_remove_effective_amount_ops( name, amt, tx_num, position, touched )) diff --git a/lbry/wallet/server/db/claimtrie.py b/lbry/wallet/server/db/claimtrie.py index 65a2b02a3..23b2cfb8d 100644 --- a/lbry/wallet/server/db/claimtrie.py +++ b/lbry/wallet/server/db/claimtrie.py @@ -133,15 +133,15 @@ class StagedClaimtrieItem(typing.NamedTuple): expiration_height: int tx_num: int position: int - root_claim_tx_num: int - root_claim_tx_position: int + root_tx_num: int + root_position: int channel_signature_is_valid: bool signing_hash: Optional[bytes] reposted_claim_hash: Optional[bytes] @property def is_update(self) -> bool: - return (self.tx_num, self.position) != (self.root_claim_tx_num, self.root_claim_tx_position) + return (self.tx_num, self.position) != (self.root_tx_num, self.root_position) def _get_add_remove_claim_utxo_ops(self, add=True): """ @@ -155,7 +155,7 @@ class StagedClaimtrieItem(typing.NamedTuple): # claim tip by claim hash op( *Prefixes.claim_to_txo.pack_item( - self.claim_hash, self.tx_num, self.position, self.root_claim_tx_num, self.root_claim_tx_position, + self.claim_hash, self.tx_num, self.position, self.root_tx_num, self.root_position, self.amount, self.channel_signature_is_valid, self.name ) ), @@ -173,7 +173,7 @@ class StagedClaimtrieItem(typing.NamedTuple): # short url resolution op( *Prefixes.claim_short_id.pack_item( - self.name, self.claim_hash, self.root_claim_tx_num, self.root_claim_tx_position, self.tx_num, + self.name, self.claim_hash, self.root_tx_num, self.root_position, self.tx_num, self.position ) ) diff --git a/lbry/wallet/server/db/revertable.py b/lbry/wallet/server/db/revertable.py index 86955add8..532e78ecd 100644 --- a/lbry/wallet/server/db/revertable.py +++ b/lbry/wallet/server/db/revertable.py @@ -91,16 +91,19 @@ class RevertableOpStack: inverted = op.invert() if self._items[op.key] and inverted == self._items[op.key][-1]: self._items[op.key].pop() + elif self._items[op.key] and self._items[op.key][-1] == op: # duplicate of last op + pass # raise an error? else: if op.is_put: stored = self._get(op.key) if stored is not None: - assert RevertableDelete(op.key, stored) in self._items[op.key], f"db op ties to add on top of existing key={op}" + assert RevertableDelete(op.key, stored) in self._items[op.key], \ + f"db op tries to add on top of existing key: {op}" self._items[op.key].append(op) else: stored = self._get(op.key) if stored is not None and stored != op.value: - assert RevertableDelete(op.key, stored) in self._items[op.key] + assert RevertableDelete(op.key, stored) in self._items[op.key], f"delete {op}" else: assert stored is not None, f"db op tries to delete nonexistent key: {op}" assert stored == op.value, f"db op tries to delete with incorrect value: {op}" diff --git a/lbry/wallet/server/leveldb.py b/lbry/wallet/server/leveldb.py index c2654e69f..aba71a8fc 100644 --- a/lbry/wallet/server/leveldb.py +++ b/lbry/wallet/server/leveldb.py @@ -300,9 +300,8 @@ class LevelDB: return def _resolve_claim_in_channel(self, channel_hash: bytes, normalized_name: str): - prefix = DB_PREFIXES.channel_to_claim.value + channel_hash + length_encoded_name(normalized_name) candidates = [] - for k, v in self.db.iterator(prefix=prefix): + for k, v in self.db.iterator(prefix=Prefixes.channel_to_claim.pack_partial_key(channel_hash, normalized_name)): key = Prefixes.channel_to_claim.unpack_key(k) stream = Prefixes.channel_to_claim.unpack_value(v) effective_amount = self.get_effective_amount(stream.claim_hash) @@ -395,6 +394,15 @@ class LevelDB: return support_only return support_amount + self._get_active_amount(claim_hash, ACTIVATED_CLAIM_TXO_TYPE, self.db_height + 1) + def get_url_effective_amount(self, name: str, tx_num: int, position: int, claim_hash: bytes): + for _k, _v in self.db.iterator(prefix=Prefixes.effective_amount.pack_partial_key(name)): + v = Prefixes.effective_amount.unpack_value(_v) + if v.claim_hash == claim_hash: + k = Prefixes.effective_amount.unpack_key(_k) + if k.tx_num == tx_num and k.position == position: + return k.effective_amount + return + def get_claims_for_name(self, name): claims = [] for _k, _v in self.db.iterator(prefix=Prefixes.claim_short_id.pack_partial_key(name)):