fix duplicate get_merkle requests
This commit is contained in:
parent
66b4ad0c44
commit
bb12ae9ce6
1 changed files with 11 additions and 3 deletions
|
@ -68,12 +68,13 @@ class BlockHeightEvent(NamedTuple):
|
||||||
|
|
||||||
|
|
||||||
class TransactionCacheItem:
|
class TransactionCacheItem:
|
||||||
__slots__ = '_tx', 'lock', 'has_tx'
|
__slots__ = '_tx', 'lock', 'has_tx', 'pending_verifications'
|
||||||
|
|
||||||
def __init__(self, tx: Optional[Transaction] = None, lock: Optional[asyncio.Lock] = None):
|
def __init__(self, tx: Optional[Transaction] = None, lock: Optional[asyncio.Lock] = None):
|
||||||
self.has_tx = asyncio.Event()
|
self.has_tx = asyncio.Event()
|
||||||
self.lock = lock or asyncio.Lock()
|
self.lock = lock or asyncio.Lock()
|
||||||
self._tx = self.tx = tx
|
self._tx = self.tx = tx
|
||||||
|
self.pending_verifications = 0
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def tx(self) -> Optional[Transaction]:
|
def tx(self) -> Optional[Transaction]:
|
||||||
|
@ -579,6 +580,14 @@ class Ledger(metaclass=LedgerRegistry):
|
||||||
(cache_item.tx.is_verified or remote_height < 1):
|
(cache_item.tx.is_verified or remote_height < 1):
|
||||||
return cache_item.tx # cached tx is already up-to-date
|
return cache_item.tx # cached tx is already up-to-date
|
||||||
|
|
||||||
|
try:
|
||||||
|
cache_item.pending_verifications += 1
|
||||||
|
return await self._update_cache_item(cache_item, txid, remote_height, check_local)
|
||||||
|
finally:
|
||||||
|
cache_item.pending_verifications -= 1
|
||||||
|
|
||||||
|
async def _update_cache_item(self, cache_item, txid, remote_height, check_local=True):
|
||||||
|
|
||||||
async with cache_item.lock:
|
async with cache_item.lock:
|
||||||
|
|
||||||
tx = cache_item.tx
|
tx = cache_item.tx
|
||||||
|
@ -595,13 +604,12 @@ class Ledger(metaclass=LedgerRegistry):
|
||||||
)
|
)
|
||||||
tx = Transaction(unhexlify(_raw), height=merkle.get('block_height'))
|
tx = Transaction(unhexlify(_raw), height=merkle.get('block_height'))
|
||||||
cache_item.tx = tx # make sure it's saved before caching it
|
cache_item.tx = tx # make sure it's saved before caching it
|
||||||
|
|
||||||
await self.maybe_verify_transaction(tx, remote_height, merkle)
|
await self.maybe_verify_transaction(tx, remote_height, merkle)
|
||||||
return tx
|
return tx
|
||||||
|
|
||||||
async def maybe_verify_transaction(self, tx, remote_height, merkle=None):
|
async def maybe_verify_transaction(self, tx, remote_height, merkle=None):
|
||||||
tx.height = remote_height
|
tx.height = remote_height
|
||||||
if 0 < remote_height < len(self.headers):
|
if 0 < remote_height < len(self.headers) and self._tx_cache[tx.id].pending_verifications == 1:
|
||||||
if not merkle:
|
if not merkle:
|
||||||
merkle = await self.network.retriable_call(self.network.get_merkle, tx.id, remote_height)
|
merkle = await self.network.retriable_call(self.network.get_merkle, tx.id, remote_height)
|
||||||
merkle_root = self.get_root_of_merkle_tree(merkle['merkle'], merkle['pos'], tx.hash)
|
merkle_root = self.get_root_of_merkle_tree(merkle['merkle'], merkle['pos'], tx.hash)
|
||||||
|
|
Loading…
Reference in a new issue