failing test for unordered mempool
This commit is contained in:
parent
96800de052
commit
925eb618de
2 changed files with 45 additions and 2 deletions
|
@ -1,6 +1,9 @@
|
|||
import logging
|
||||
import asyncio
|
||||
import random
|
||||
from itertools import chain
|
||||
from random import shuffle
|
||||
|
||||
from torba.testcase import IntegrationTestCase
|
||||
from torba.client.util import satoshis_to_coins, coins_to_satoshis
|
||||
|
||||
|
@ -129,3 +132,39 @@ class BasicTransactionTests(IntegrationTestCase):
|
|||
self.assertEqual(tx.outputs[0].get_address(self.ledger), address2)
|
||||
self.assertEqual(tx.outputs[0].is_change, False)
|
||||
self.assertEqual(tx.outputs[1].is_change, True)
|
||||
|
||||
async def test_history_edge_cases(self):
|
||||
await self.assertBalance(self.account, '0.0')
|
||||
address = await self.account.receiving.get_or_create_usable_address()
|
||||
# evil trick: mempool is unsorted on real life, but same order between python instances. reproduce it
|
||||
original_summary = self.conductor.spv_node.server.mempool.transaction_summaries
|
||||
async def random_summary(*args, **kwargs):
|
||||
summary = await original_summary(*args, **kwargs)
|
||||
if summary and len(summary) > 2:
|
||||
ordered = summary.copy()
|
||||
while summary == ordered:
|
||||
random.shuffle(summary)
|
||||
return summary
|
||||
self.conductor.spv_node.server.mempool.transaction_summaries = random_summary
|
||||
# 10 unconfirmed txs, all from blockchain wallet
|
||||
sends = list(self.blockchain.send_to_address(address, 10) for _ in range(10))
|
||||
# use batching to reduce issues with send_to_address on cli
|
||||
for batch in range(0, len(sends), 10):
|
||||
txids = await asyncio.gather(*sends[batch:batch + 10])
|
||||
await asyncio.wait([self.on_transaction_id(txid) for txid in txids])
|
||||
remote_status = await self.ledger.network.subscribe_address(address)
|
||||
self.assertTrue(await self.ledger.update_history(address, remote_status))
|
||||
# 20 unconfirmed txs, 10 from blockchain, 10 from local to local
|
||||
utxos = await self.account.get_utxos()
|
||||
txs = []
|
||||
for utxo in utxos:
|
||||
tx = await self.ledger.transaction_class.create(
|
||||
[self.ledger.transaction_class.input_class.spend(utxo)],
|
||||
[],
|
||||
[self.account], self.account
|
||||
)
|
||||
await self.broadcast(tx)
|
||||
txs.append(tx)
|
||||
await asyncio.wait([self.on_transaction_address(tx, address) for tx in txs], timeout=1)
|
||||
remote_status = await self.ledger.network.subscribe_address(address)
|
||||
self.assertTrue(await self.ledger.update_history(address, remote_status))
|
||||
|
|
|
@ -415,7 +415,7 @@ class BaseLedger(metaclass=LedgerRegistry):
|
|||
local_status, local_history = await self.get_local_status_and_history(address)
|
||||
|
||||
if local_status == remote_status:
|
||||
return
|
||||
return True
|
||||
|
||||
remote_history = await self.network.retriable_call(self.network.get_history, address)
|
||||
|
||||
|
@ -472,14 +472,18 @@ class BaseLedger(metaclass=LedgerRegistry):
|
|||
|
||||
local_status, local_history = await self.get_local_status_and_history(address)
|
||||
if local_status != remote_status:
|
||||
remote_history = list(map(itemgetter('tx_hash', 'height'), remote_history))
|
||||
if remote_history == local_history:
|
||||
return True
|
||||
log.debug(
|
||||
"Wallet is out of sync after syncing. Remote: %s with %d items, local: %s with %d items",
|
||||
remote_status, len(remote_history), local_status, len(local_history)
|
||||
)
|
||||
log.debug("local: %s", local_history)
|
||||
log.debug("remote: %s", remote_history)
|
||||
return False
|
||||
else:
|
||||
log.debug("Sync completed for: %s", address)
|
||||
return True
|
||||
|
||||
async def cache_transaction(self, txid, remote_height):
|
||||
cache_item = self._tx_cache.get(txid)
|
||||
|
|
Loading…
Reference in a new issue