import os import asyncio import logging import aiohttp from sqlalchemy import text from lbry.testcase import IntegrationTestCase, WalletNode, CommandTestCase from lbry.constants import CENT from lbry.wallet import WalletManager, RegTestLedger, Transaction, Output from lbry.blockchain import Lbrycrd from lbry.db import Database, TXI from lbry.blockchain import Synchronizer class SyncTests(IntegrationTestCase): VERBOSITY = logging.WARN def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.api_port = 5280 self.started_nodes = [] async def asyncTearDown(self): for node in self.started_nodes: try: await node.stop(cleanup=True) except Exception as e: print(e) await super().asyncTearDown() async def make_wallet_node(self, seed=None): self.api_port += 1 wallet_node = WalletNode(WalletManager, RegTestLedger, port=self.api_port) await wallet_node.start(self.conductor.spv_node, seed) self.started_nodes.append(wallet_node) return wallet_node async def test_nodes_with_same_account_stay_in_sync(self): # destination node/account for receiving TXs node0 = await self.make_wallet_node() account0 = node0.account # main node/account creating TXs node1 = self.wallet_node account1 = self.wallet_node.account # mirror node/account, expected to reflect everything in main node as it happens node2 = await self.make_wallet_node(account1.seed) account2 = node2.account self.assertNotEqual(account0.id, account1.id) self.assertEqual(account1.id, account2.id) await self.assertBalance(account0, '0.0') await self.assertBalance(account1, '0.0') await self.assertBalance(account2, '0.0') self.assertEqual(await account0.get_address_count(chain=0), 20) self.assertEqual(await account1.get_address_count(chain=0), 20) self.assertEqual(await account2.get_address_count(chain=0), 20) self.assertEqual(await account1.get_address_count(chain=1), 6) self.assertEqual(await account2.get_address_count(chain=1), 6) # check that main node and mirror node generate 5 address to fill gap fifth_address = (await account1.receiving.get_addresses())[4] await self.blockchain.send_to_address(fifth_address, 1.00) await asyncio.wait([ account1.ledger.on_address.first, account2.ledger.on_address.first ]) self.assertEqual(await account1.get_address_count(chain=0), 25) self.assertEqual(await account2.get_address_count(chain=0), 25) await self.assertBalance(account1, '1.0') await self.assertBalance(account2, '1.0') await self.blockchain.generate(1) # pay 0.01 from main node to receiving node, would have increased change addresses address0 = (await account0.receiving.get_addresses())[0] hash0 = self.ledger.address_to_hash160(address0) tx = await Transaction.create( [], [Output.pay_pubkey_hash(CENT, hash0)], [account1], account1 ) await self.broadcast(tx) await asyncio.wait([ account0.ledger.wait(tx), account1.ledger.wait(tx), account2.ledger.wait(tx), ]) await self.blockchain.generate(1) await asyncio.wait([ account0.ledger.wait(tx), account1.ledger.wait(tx), account2.ledger.wait(tx), ]) self.assertEqual(await account0.get_address_count(chain=0), 21) self.assertGreater(await account1.get_address_count(chain=1), 6) self.assertGreater(await account2.get_address_count(chain=1), 6) await self.assertBalance(account0, '0.01') await self.assertBalance(account1, '0.989876') await self.assertBalance(account2, '0.989876') await self.blockchain.generate(1) # create a new mirror node and see if it syncs to same balance from scratch node3 = await self.make_wallet_node(account1.seed) account3 = node3.account await self.assertBalance(account3, '0.989876')