fix restriction rules, minor refactor, translate error from transaction not found into returning none

This commit is contained in:
Victor Shyba 2019-08-31 06:37:17 -03:00
parent d2cd0ece5f
commit 379144bcfe
6 changed files with 22 additions and 17 deletions

View file

@ -138,6 +138,7 @@ class BasicTransactionTests(IntegrationTestCase):
address = await self.account.receiving.get_or_create_usable_address() 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 # 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 original_summary = self.conductor.spv_node.server.mempool.transaction_summaries
async def random_summary(*args, **kwargs): async def random_summary(*args, **kwargs):
summary = await original_summary(*args, **kwargs) summary = await original_summary(*args, **kwargs)
if summary and len(summary) > 2: if summary and len(summary) > 2:
@ -174,3 +175,5 @@ class BasicTransactionTests(IntegrationTestCase):
self.assertTrue(await self.ledger.update_history(address, remote_status)) self.assertTrue(await self.ledger.update_history(address, remote_status))
self.assertEqual(21, len((await self.ledger.get_local_status_and_history(address))[1])) self.assertEqual(21, len((await self.ledger.get_local_status_and_history(address))[1]))
self.assertEqual(0, len(self.ledger._known_addresses_out_of_sync)) self.assertEqual(0, len(self.ledger._known_addresses_out_of_sync))
# should be another test, but it would be too much to setup just for that and it affects sync
self.assertIsNone(await self.ledger.network.get_transaction('1'*64))

View file

@ -29,7 +29,7 @@ class MockNetwork:
async def get_merkle(self, txid, height): async def get_merkle(self, txid, height):
return {'merkle': ['abcd01'], 'pos': 1} return {'merkle': ['abcd01'], 'pos': 1}
async def get_transaction(self, tx_hash): async def get_transaction(self, tx_hash, _=None):
self.get_transaction_called.append(tx_hash) self.get_transaction_called.append(tx_hash)
return self.transaction[tx_hash] return self.transaction[tx_hash]

View file

@ -220,7 +220,7 @@ class SQLiteMixin:
async def open(self): async def open(self):
log.info("connecting to database: %s", self._db_path) log.info("connecting to database: %s", self._db_path)
self.db = await AIOSQLite.connect(self._db_path) self.db = await AIOSQLite.connect(self._db_path, isolation_level=None)
await self.db.executescript(self.CREATE_TABLES_QUERY) await self.db.executescript(self.CREATE_TABLES_QUERY)
async def close(self): async def close(self):

View file

@ -287,7 +287,7 @@ class BaseLedger(metaclass=LedgerRegistry):
await self.join_network() await self.join_network()
self.network.on_connected.listen(self.join_network) self.network.on_connected.listen(self.join_network)
async def join_network(self, *args): async def join_network(self, *_):
log.info("Subscribing and updating accounts.") log.info("Subscribing and updating accounts.")
async with self._header_processing_lock: async with self._header_processing_lock:
await self.update_headers() await self.update_headers()
@ -472,9 +472,10 @@ class BaseLedger(metaclass=LedgerRegistry):
await self.db.save_transaction_io_batch( await self.db.save_transaction_io_batch(
synced_txs, address, self.address_to_hash160(address), synced_history.getvalue() synced_txs, address, self.address_to_hash160(address), synced_history.getvalue()
) )
await asyncio.wait([
for tx in synced_txs: self._on_transaction_controller.add(TransactionEvent(address, tx))
await self._on_transaction_controller.add(TransactionEvent(address, tx)) for tx in synced_txs
])
if address_manager is None: if address_manager is None:
address_manager = await self.get_address_manager_for_address(address) address_manager = await self.get_address_manager_for_address(address)
@ -517,7 +518,7 @@ class BaseLedger(metaclass=LedgerRegistry):
if tx is None: if tx is None:
# fetch from network # fetch from network
_raw = await self.network.retriable_call(self.network.get_transaction, txid) _raw = await self.network.retriable_call(self.network.get_transaction, txid, remote_height)
if _raw: if _raw:
tx = self.transaction_class(unhexlify(_raw)) tx = self.transaction_class(unhexlify(_raw))
cache_item.tx = tx # make sure it's saved before caching it cache_item.tx = tx # make sure it's saved before caching it

View file

@ -72,6 +72,10 @@ class ClientSession(BaseClientSession):
log.debug("got reply for %s from %s:%i", method, *self.server) log.debug("got reply for %s from %s:%i", method, *self.server)
return reply return reply
except RPCError as e: except RPCError as e:
if str(e).find('.*no such .*transaction.*') and args:
# shouldnt the server return none instead?
log.warning("Requested transaction missing from server: %s", args[0])
return None
log.warning("Wallet server (%s:%i) returned an error. Code: %s Message: %s", log.warning("Wallet server (%s:%i) returned an error. Code: %s Message: %s",
*self.server, *e.args) *self.server, *e.args)
raise e raise e
@ -220,20 +224,17 @@ class BaseNetwork:
def _update_remote_height(self, header_args): def _update_remote_height(self, header_args):
self.remote_height = header_args[0]["height"] self.remote_height = header_args[0]["height"]
def get_transaction(self, tx_hash): def get_transaction(self, tx_hash, known_height=None):
return self.rpc('blockchain.transaction.get', [tx_hash]) # use any server if its old, otherwise restrict to who gave us the history
restricted = not known_height or 0 > known_height > self.remote_height - 10
return self.rpc('blockchain.transaction.get', [tx_hash], restricted)
def get_transaction_height(self, tx_hash, known_height=None): def get_transaction_height(self, tx_hash, known_height=None):
restricted = True # by default, check master for consistency restricted = not known_height or 0 > known_height > self.remote_height - 10
if known_height:
if 0 < known_height < self.remote_height - 10:
restricted = False # we can get from any server, its old
return self.rpc('blockchain.transaction.get_height', [tx_hash], restricted) return self.rpc('blockchain.transaction.get_height', [tx_hash], restricted)
def get_merkle(self, tx_hash, height): def get_merkle(self, tx_hash, height):
restricted = True # by default, check master for consistency restricted = 0 > height > self.remote_height - 10
if 0 < height < self.remote_height - 10:
restricted = False # we can get from any server, its old
return self.rpc('blockchain.transaction.get_merkle', [tx_hash, height], restricted) return self.rpc('blockchain.transaction.get_merkle', [tx_hash, height], restricted)
def get_headers(self, height, count=10000): def get_headers(self, height, count=10000):