Exemple #1
0
    async def test_wallet_coinbase_reorg(self, wallet_node):
        num_blocks = 5
        full_nodes, wallets = wallet_node
        full_node_api = full_nodes[0]
        fn_server = full_node_api.full_node.server
        wallet_node, server_2 = wallets[0]
        wallet = wallet_node.wallet_state_manager.main_wallet
        ph = await wallet.get_new_puzzlehash()

        await server_2.start_client(
            PeerInfo(self_hostname, uint16(fn_server._port)), None)
        for i in range(0, num_blocks):
            await full_node_api.farm_new_transaction_block(
                FarmNewBlockProtocol(ph))

        funds = sum([
            calculate_pool_reward(uint32(i)) +
            calculate_base_farmer_reward(uint32(i))
            for i in range(1, num_blocks)
        ])

        await time_out_assert(5, wallet.get_confirmed_balance, funds)

        await full_node_api.reorg_from_index_to_new_index(
            ReorgProtocol(uint32(3), uint32(num_blocks + 6), 32 * b"0"))

        funds = sum([
            calculate_pool_reward(uint32(i)) +
            calculate_base_farmer_reward(uint32(i))
            for i in range(1, num_blocks - 2)
        ])

        await time_out_assert(5, wallet.get_confirmed_balance, funds)
Exemple #2
0
    async def test_wallet_tx_reorg(self, two_wallet_nodes, trusted):
        num_blocks = 5
        full_nodes, wallets = two_wallet_nodes
        full_node_api = full_nodes[0]
        fn_server = full_node_api.full_node.server
        wallet_node, server_2 = wallets[0]
        wallet_node: WalletNode = wallet_node
        wallet_node_2, server_3 = wallets[1]
        wallet = wallet_node.wallet_state_manager.main_wallet
        wallet_2 = wallet_node_2.wallet_state_manager.main_wallet

        ph = await wallet.get_new_puzzlehash()
        ph2 = await wallet_2.get_new_puzzlehash()
        if trusted:
            wallet_node.config["trusted_peers"] = {
                fn_server.node_id.hex(): fn_server.node_id.hex()
            }
            wallet_node_2.config["trusted_peers"] = {
                fn_server.node_id.hex(): fn_server.node_id.hex()
            }
        else:
            wallet_node.config["trusted_peers"] = {}
            wallet_node_2.config["trusted_peers"] = {}

        await server_2.start_client(
            PeerInfo(self_hostname, uint16(fn_server._port)), None)
        await server_3.start_client(
            PeerInfo(self_hostname, uint16(fn_server._port)), None)
        for i in range(0, num_blocks):
            await full_node_api.farm_new_transaction_block(
                FarmNewBlockProtocol(ph))

        funds = sum([
            calculate_pool_reward(uint32(i)) +
            calculate_base_farmer_reward(uint32(i))
            for i in range(1, num_blocks)
        ])
        # Waits a few seconds to receive rewards
        all_blocks = await full_node_api.get_all_full_blocks()

        # Ensure that we use a coin that we will not reorg out
        coin = list(all_blocks[-3].get_included_reward_coins())[0]
        await asyncio.sleep(5)

        tx = await wallet.generate_signed_transaction(1000, ph2, coins={coin})
        await wallet.push_transaction(tx)
        await full_node_api.full_node.respond_transaction(
            tx.spend_bundle, tx.name)
        await time_out_assert(
            5, full_node_api.full_node.mempool_manager.get_spendbundle,
            tx.spend_bundle, tx.name)
        await time_out_assert(5, wallet.get_confirmed_balance, funds)
        for i in range(0, 2):
            await full_node_api.farm_new_transaction_block(
                FarmNewBlockProtocol(32 * b"0"))
        await time_out_assert(5, wallet_2.get_confirmed_balance, 1000)

        await time_out_assert(
            5, wallet_node.wallet_state_manager.blockchain.get_peak_height, 7)
        peak_height = full_node_api.full_node.blockchain.get_peak().height
        print(peak_height)

        # Perform a reorg, which will revert the transaction in the full node and wallet, and cause wallet to resubmit
        await full_node_api.reorg_from_index_to_new_index(
            ReorgProtocol(uint32(peak_height - 3), uint32(peak_height + 3),
                          32 * b"0"))

        funds = sum([
            calculate_pool_reward(uint32(i)) +
            calculate_base_farmer_reward(uint32(i))
            for i in range(1, peak_height - 2)
        ])

        await time_out_assert(
            7, full_node_api.full_node.blockchain.get_peak_height,
            peak_height + 3)
        await time_out_assert(
            7, wallet_node.wallet_state_manager.blockchain.get_peak_height,
            peak_height + 3)

        # Farm a few blocks so we can confirm the resubmitted transaction
        for i in range(0, num_blocks):
            await asyncio.sleep(1)
            await full_node_api.farm_new_transaction_block(
                FarmNewBlockProtocol(32 * b"0"))

        # By this point, the transaction should be confirmed
        await time_out_assert(15, wallet.get_confirmed_balance, funds - 1000)

        unconfirmed = await wallet_node.wallet_state_manager.tx_store.get_unconfirmed_for_wallet(
            int(wallet.id()))
        assert len(unconfirmed) == 0
        tx_record = await wallet_node.wallet_state_manager.tx_store.get_transaction_record(
            tx.name)
        removed = tx_record.removals[0]
        added = tx_record.additions[0]
        added_1 = tx_record.additions[1]
        wallet_coin_record_rem = await wallet_node.wallet_state_manager.coin_store.get_coin_record(
            removed.name())
        assert wallet_coin_record_rem.spent

        coin_record_full_node = await full_node_api.full_node.coin_store.get_coin_record(
            removed.name())
        assert coin_record_full_node.spent
        add_1_coin_record_full_node = await full_node_api.full_node.coin_store.get_coin_record(
            added.name())
        assert add_1_coin_record_full_node is not None
        assert add_1_coin_record_full_node.confirmed_block_index > 0
        add_2_coin_record_full_node = await full_node_api.full_node.coin_store.get_coin_record(
            added_1.name())
        assert add_2_coin_record_full_node is not None
        assert add_2_coin_record_full_node.confirmed_block_index > 0
    async def test_create_multiple_pool_wallets(self, one_wallet_node_and_rpc):
        client, wallet_node_0, full_node_api = one_wallet_node_and_rpc
        wallet_0 = wallet_node_0.wallet_state_manager.main_wallet
        our_ph_1 = await wallet_0.get_new_puzzlehash()
        our_ph_2 = await wallet_0.get_new_puzzlehash()
        summaries_response = await client.get_wallets()
        for summary in summaries_response:
            if WalletType(int(summary["type"])) == WalletType.POOLING_WALLET:
                assert False

        creation_tx: TransactionRecord = await client.create_new_pool_wallet(
            our_ph_1, "", 0, "localhost:5000", "new", "SELF_POOLING"
        )
        creation_tx_2: TransactionRecord = await client.create_new_pool_wallet(
            our_ph_1, "localhost", 12, "localhost:5000", "new", "FARMING_TO_POOL"
        )

        await time_out_assert(
            10,
            full_node_api.full_node.mempool_manager.get_spendbundle,
            creation_tx.spend_bundle,
            creation_tx.name,
        )
        await time_out_assert(
            10,
            full_node_api.full_node.mempool_manager.get_spendbundle,
            creation_tx_2.spend_bundle,
            creation_tx_2.name,
        )

        await self.farm_blocks(full_node_api, our_ph_2, 6)
        assert full_node_api.full_node.mempool_manager.get_spendbundle(creation_tx.name) is None
        assert full_node_api.full_node.mempool_manager.get_spendbundle(creation_tx_2.name) is None

        await asyncio.sleep(3)
        status_2: PoolWalletInfo = (await client.pw_status(2))[0]
        status_3: PoolWalletInfo = (await client.pw_status(3))[0]

        if status_2.current.state == PoolSingletonState.SELF_POOLING.value:
            assert status_3.current.state == PoolSingletonState.FARMING_TO_POOL.value
        else:
            assert status_2.current.state == PoolSingletonState.FARMING_TO_POOL.value
            assert status_3.current.state == PoolSingletonState.SELF_POOLING.value

        full_config: Dict = load_config(wallet_0.wallet_state_manager.root_path, "config.yaml")
        pool_list: List[Dict] = full_config["pool"]["pool_list"]
        assert len(pool_list) == 2

        p2_singleton_ph_2: bytes32 = status_2.p2_singleton_puzzle_hash
        p2_singleton_ph_3: bytes32 = status_3.p2_singleton_puzzle_hash
        assert (
            await wallet_node_0.wallet_state_manager.interested_store.get_interested_puzzle_hash_wallet_id(
                p2_singleton_ph_2
            )
        ) is not None
        assert (
            await wallet_node_0.wallet_state_manager.interested_store.get_interested_puzzle_hash_wallet_id(
                p2_singleton_ph_3
            )
        ) is not None
        assert len(await wallet_node_0.wallet_state_manager.tx_store.get_unconfirmed_for_wallet(2)) == 0
        assert len(await wallet_node_0.wallet_state_manager.tx_store.get_unconfirmed_for_wallet(3)) == 0
        # Doing a reorg reverts and removes the pool wallets
        await full_node_api.reorg_from_index_to_new_index(ReorgProtocol(uint32(0), uint32(20), our_ph_2))
        await asyncio.sleep(5)
        summaries_response = await client.get_wallets()
        assert len(summaries_response) == 1

        with pytest.raises(ValueError):
            await client.pw_status(2)
        with pytest.raises(ValueError):
            await client.pw_status(3)
        # It also removed interested PH, so we can recreated the pool wallet with another wallet_id later
        assert (
            await wallet_node_0.wallet_state_manager.interested_store.get_interested_puzzle_hash_wallet_id(
                p2_singleton_ph_2
            )
        ) is None
        assert (
            await wallet_node_0.wallet_state_manager.interested_store.get_interested_puzzle_hash_wallet_id(
                p2_singleton_ph_3
            )
        ) is None
Exemple #4
0
    async def test_subscribe_for_coin_id_reorg(self, wallet_node_simulator):
        num_blocks = 4
        long_blocks = 20
        full_nodes, wallets = wallet_node_simulator
        full_node_api = full_nodes[0]
        wallet_node, server_2 = wallets[0]
        fn_server = full_node_api.full_node.server
        wsm: WalletStateManager = wallet_node.wallet_state_manager
        standard_wallet: Wallet = wsm.wallets[1]
        puzzle_hash = await standard_wallet.get_new_puzzlehash()

        await server_2.start_client(
            PeerInfo(self_hostname, uint16(fn_server._port)), None)
        incoming_queue, peer_id = await add_dummy_connection(
            fn_server, 12312, NodeType.WALLET)

        fake_wallet_peer = fn_server.all_connections[peer_id]
        zero_ph = 32 * b"\0"

        # Farm to create a coin that we'll track
        for i in range(0, num_blocks):
            await full_node_api.farm_new_transaction_block(
                FarmNewBlockProtocol(zero_ph))

        for i in range(0, long_blocks):
            await full_node_api.farm_new_transaction_block(
                FarmNewBlockProtocol(zero_ph))

        await full_node_api.farm_new_transaction_block(
            FarmNewBlockProtocol(puzzle_hash))

        for i in range(0, num_blocks):
            await full_node_api.farm_new_transaction_block(
                FarmNewBlockProtocol(zero_ph))

        expected_height = uint32(long_blocks + 2 * num_blocks + 1)
        await time_out_assert(
            15, full_node_api.full_node.blockchain.get_peak_height,
            expected_height)

        coin_records = await full_node_api.full_node.coin_store.get_coin_records_by_puzzle_hash(
            True, puzzle_hash)
        assert len(coin_records) > 0

        for coin_rec in coin_records:
            msg = wallet_protocol.RegisterForCoinUpdates([coin_rec.name], 0)
            msg_response = await full_node_api.register_interest_in_coin(
                msg, fake_wallet_peer)
            assert msg_response is not None

        fork_height = expected_height - num_blocks - 5
        req = ReorgProtocol(fork_height, expected_height + 5, zero_ph)
        await full_node_api.reorg_from_index_to_new_index(req)

        coin_records = await full_node_api.full_node.coin_store.get_coin_records_by_puzzle_hash(
            True, puzzle_hash)
        assert coin_records == []

        all_messages = await self.get_all_messages_in_queue(incoming_queue)

        coin_update_messages = []
        for message in all_messages:
            if message.type == ProtocolMessageTypes.coin_state_update.value:
                data_response: CoinStateUpdate = CoinStateUpdate.from_bytes(
                    message.data)
                coin_update_messages.append(data_response)

        assert len(coin_update_messages) == 1
        update = coin_update_messages[0]
        coin_states = update.items
        assert len(coin_states) == 2
        first_coin = coin_states[0]
        assert first_coin.spent_height is None
        assert first_coin.created_height is None
        second_coin = coin_states[1]
        assert second_coin.spent_height is None
        assert second_coin.created_height is None
    async def test_create_multiple_pool_wallets(self, one_wallet_node_and_rpc, fee, trusted):
        client, wallet_node_0, full_node_api = one_wallet_node_and_rpc
        if trusted:
            wallet_node_0.config["trusted_peers"] = {
                full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
            }
        else:
            wallet_node_0.config["trusted_peers"] = {}

        await wallet_node_0.server.start_client(
            PeerInfo(self_hostname, uint16(full_node_api.full_node.server._port)), None
        )
        total_block_rewards = await self.get_total_block_rewards(PREFARMED_BLOCKS)
        wallet_0 = wallet_node_0.wallet_state_manager.main_wallet
        await time_out_assert(10, wallet_0.get_confirmed_balance, total_block_rewards)
        await time_out_assert(10, wallet_node_0.wallet_state_manager.blockchain.get_peak_height, PREFARMED_BLOCKS)

        our_ph_1 = await wallet_0.get_new_puzzlehash()
        our_ph_2 = await wallet_0.get_new_puzzlehash()
        summaries_response = await client.get_wallets()
        for summary in summaries_response:
            if WalletType(int(summary["type"])) == WalletType.POOLING_WALLET:
                assert False

        creation_tx: TransactionRecord = await client.create_new_pool_wallet(
            our_ph_1, "", 0, "localhost:5000", "new", "SELF_POOLING", fee
        )
        creation_tx_2: TransactionRecord = await client.create_new_pool_wallet(
            our_ph_1, "localhost", 12, "localhost:5000", "new", "FARMING_TO_POOL", fee
        )

        await time_out_assert(
            10,
            full_node_api.full_node.mempool_manager.get_spendbundle,
            creation_tx.spend_bundle,
            creation_tx.name,
        )
        await time_out_assert(
            10,
            full_node_api.full_node.mempool_manager.get_spendbundle,
            creation_tx_2.spend_bundle,
            creation_tx_2.name,
        )

        await self.farm_blocks(full_node_api, our_ph_2, 6)
        assert full_node_api.full_node.mempool_manager.get_spendbundle(creation_tx.name) is None
        assert full_node_api.full_node.mempool_manager.get_spendbundle(creation_tx_2.name) is None

        await asyncio.sleep(3)
        status_2: PoolWalletInfo = (await client.pw_status(2))[0]
        status_3: PoolWalletInfo = (await client.pw_status(3))[0]

        if status_2.current.state == PoolSingletonState.SELF_POOLING.value:
            assert status_3.current.state == PoolSingletonState.FARMING_TO_POOL.value
        else:
            assert status_2.current.state == PoolSingletonState.FARMING_TO_POOL.value
            assert status_3.current.state == PoolSingletonState.SELF_POOLING.value

        full_config: Dict = load_config(wallet_0.wallet_state_manager.root_path, "config.yaml")
        pool_list: List[Dict] = full_config["pool"]["pool_list"]
        assert len(pool_list) == 2

        assert len(await wallet_node_0.wallet_state_manager.tx_store.get_unconfirmed_for_wallet(2)) == 0
        assert len(await wallet_node_0.wallet_state_manager.tx_store.get_unconfirmed_for_wallet(3)) == 0
        # Doing a reorg reverts and removes the pool wallets
        await full_node_api.reorg_from_index_to_new_index(ReorgProtocol(uint32(0), uint32(20), our_ph_2))
        await asyncio.sleep(5)
        summaries_response = await client.get_wallets()
        assert len(summaries_response) == 1

        with pytest.raises(ValueError):
            await client.pw_status(2)
        with pytest.raises(ValueError):
            await client.pw_status(3)

        def wallet_is_synced():
            return (
                wallet_node_0.wallet_state_manager.blockchain.get_peak_height()
                == full_node_api.full_node.blockchain.get_peak_height()
            )

        # Create some CAT wallets to increase wallet IDs
        for i in range(5):
            res = await client.create_new_cat_and_wallet(20)
            await asyncio.sleep(2)
            summaries_response = await client.get_wallets()
            assert res["success"]
            cat_0_id = res["wallet_id"]
            asset_id = bytes.fromhex(res["asset_id"])
            assert len(asset_id) > 0
            await self.farm_blocks(full_node_api, our_ph_2, 6)
            await time_out_assert(20, wallet_is_synced)
            bal_0 = await client.get_wallet_balance(cat_0_id)
            assert bal_0["confirmed_wallet_balance"] == 20

        # Test creation of many pool wallets. Use untrusted since that is the more complicated protocol, but don't
        # run this code more than once, since it's slow.
        if fee == 0 and not trusted:
            for i in range(22):
                creation_tx_3: TransactionRecord = await client.create_new_pool_wallet(
                    our_ph_1, "localhost", 5, "localhost:5000", "new", "FARMING_TO_POOL", fee
                )
                await time_out_assert(
                    10,
                    full_node_api.full_node.mempool_manager.get_spendbundle,
                    creation_tx_3.spend_bundle,
                    creation_tx_3.name,
                )
                await self.farm_blocks(full_node_api, our_ph_2, 2)
                await time_out_assert(20, wallet_is_synced)

                full_config: Dict = load_config(wallet_0.wallet_state_manager.root_path, "config.yaml")
                pool_list: List[Dict] = full_config["pool"]["pool_list"]
                assert len(pool_list) == i + 3
                if i == 0:
                    # Ensures that the CAT creation does not cause pool wallet IDs to increment
                    for wallet in wallet_node_0.wallet_state_manager.wallets.values():
                        if wallet.type() == WalletType.POOLING_WALLET:
                            status: PoolWalletInfo = (await client.pw_status(wallet.id()))[0]
                            assert (await wallet.get_pool_wallet_index()) < 5
                            auth_sk = find_authentication_sk(
                                [wallet_0.wallet_state_manager.private_key], status.current.owner_pubkey
                            )
                            assert auth_sk is not None
                            owner_sk = find_owner_sk(
                                [wallet_0.wallet_state_manager.private_key], status.current.owner_pubkey
                            )
                            assert owner_sk is not None
                            assert owner_sk != auth_sk
    async def test1(self, two_nodes):
        num_blocks = 5
        test_rpc_port = uint16(21522)
        nodes, _ = two_nodes
        full_node_api_1, full_node_api_2 = nodes
        server_1 = full_node_api_1.full_node.server
        server_2 = full_node_api_2.full_node.server

        def stop_node_cb():
            full_node_api_1._close()
            server_1.close_all()

        full_node_rpc_api = FullNodeRpcApi(full_node_api_1.full_node)

        config = bt.config
        hostname = config["self_hostname"]
        daemon_port = config["daemon_port"]

        rpc_cleanup = await start_rpc_server(
            full_node_rpc_api,
            hostname,
            daemon_port,
            test_rpc_port,
            stop_node_cb,
            bt.root_path,
            config,
            connect_to_daemon=False,
        )

        try:
            client = await FullNodeRpcClient.create(self_hostname,
                                                    test_rpc_port,
                                                    bt.root_path, config)
            await validate_get_routes(client, full_node_rpc_api)
            state = await client.get_blockchain_state()
            assert state["peak"] is None
            assert not state["sync"]["sync_mode"]
            assert state["difficulty"] > 0
            assert state["sub_slot_iters"] > 0

            blocks = bt.get_consecutive_blocks(num_blocks)
            blocks = bt.get_consecutive_blocks(
                num_blocks,
                block_list_input=blocks,
                guarantee_transaction_block=True)

            assert len(await client.get_unfinished_block_headers()) == 0
            assert len((await client.get_block_records(0, 100))) == 0
            for block in blocks:
                if is_overflow_block(
                        test_constants,
                        block.reward_chain_block.signage_point_index):
                    finished_ss = block.finished_sub_slots[:-1]
                else:
                    finished_ss = block.finished_sub_slots

                unf = UnfinishedBlock(
                    finished_ss,
                    block.reward_chain_block.get_unfinished(),
                    block.challenge_chain_sp_proof,
                    block.reward_chain_sp_proof,
                    block.foliage,
                    block.foliage_transaction_block,
                    block.transactions_info,
                    block.transactions_generator,
                    [],
                )
                await full_node_api_1.full_node.respond_unfinished_block(
                    full_node_protocol.RespondUnfinishedBlock(unf), None)
                await full_node_api_1.full_node.respond_block(
                    full_node_protocol.RespondBlock(block), None)

            assert len(await client.get_unfinished_block_headers()) > 0
            assert len(await client.get_all_block(0, 2)) == 2
            state = await client.get_blockchain_state()

            block = await client.get_block(state["peak"].header_hash)
            assert block == blocks[-1]
            assert (await client.get_block(bytes([1] * 32))) is None

            assert (await client.get_block_record_by_height(2)
                    ).header_hash == blocks[2].header_hash

            assert len((await client.get_block_records(0,
                                                       100))) == num_blocks * 2

            assert (await client.get_block_record_by_height(100)) is None

            ph = list(blocks[-1].get_included_reward_coins())[0].puzzle_hash
            coins = await client.get_coin_records_by_puzzle_hash(ph)
            print(coins)
            assert len(coins) >= 1

            pid = list(
                blocks[-1].get_included_reward_coins())[0].parent_coin_info
            pid_2 = list(
                blocks[-1].get_included_reward_coins())[1].parent_coin_info
            coins = await client.get_coin_records_by_parent_ids([pid, pid_2])
            print(coins)
            assert len(coins) == 2

            name = list(blocks[-1].get_included_reward_coins())[0].name()
            name_2 = list(blocks[-1].get_included_reward_coins())[1].name()
            coins = await client.get_coin_records_by_names([name, name_2])
            print(coins)
            assert len(coins) == 2

            additions, removals = await client.get_additions_and_removals(
                blocks[-1].header_hash)
            assert len(additions) >= 2 and len(removals) == 0

            wallet = WalletTool(full_node_api_1.full_node.constants)
            wallet_receiver = WalletTool(
                full_node_api_1.full_node.constants,
                AugSchemeMPL.key_gen(std_hash(b"123123")))
            ph = wallet.get_new_puzzlehash()
            ph_2 = wallet.get_new_puzzlehash()
            ph_receiver = wallet_receiver.get_new_puzzlehash()

            assert len(await client.get_coin_records_by_puzzle_hash(ph)) == 0
            assert len(
                await client.get_coin_records_by_puzzle_hash(ph_receiver)) == 0
            blocks = bt.get_consecutive_blocks(
                2,
                block_list_input=blocks,
                guarantee_transaction_block=True,
                farmer_reward_puzzle_hash=ph,
                pool_reward_puzzle_hash=ph,
            )
            for block in blocks[-2:]:
                await full_node_api_1.full_node.respond_block(
                    full_node_protocol.RespondBlock(block))
            assert len(await client.get_coin_records_by_puzzle_hash(ph)) == 2
            assert len(
                await client.get_coin_records_by_puzzle_hash(ph_receiver)) == 0

            coin_to_spend = list(blocks[-1].get_included_reward_coins())[0]

            spend_bundle = wallet.generate_signed_transaction(
                coin_to_spend.amount, ph_receiver, coin_to_spend)

            assert len(await client.get_all_mempool_items()) == 0
            assert len(await client.get_all_mempool_tx_ids()) == 0
            assert (await client.get_mempool_item_by_tx_id(spend_bundle.name()
                                                           )) is None

            await client.push_tx(spend_bundle)
            coin = spend_bundle.additions()[0]

            assert len(await client.get_all_mempool_items()) == 1
            assert len(await client.get_all_mempool_tx_ids()) == 1
            assert (SpendBundle.from_json_dict(
                list((await client.get_all_mempool_items()
                      ).values())[0]["spend_bundle"]) == spend_bundle)
            assert (await
                    client.get_all_mempool_tx_ids())[0] == spend_bundle.name()
            assert (SpendBundle.from_json_dict(
                (await client.get_mempool_item_by_tx_id(
                    spend_bundle.name()))["spend_bundle"]) == spend_bundle)
            assert (await client.get_coin_record_by_name(coin.name())) is None

            await full_node_api_1.farm_new_transaction_block(
                FarmNewBlockProtocol(ph_2))

            assert (await
                    client.get_coin_record_by_name(coin.name())).coin == coin

            assert len(
                await client.get_coin_records_by_puzzle_hash(ph_receiver)) == 1
            assert len(
                list(
                    filter(lambda cr: not cr.spent,
                           (await
                            client.get_coin_records_by_puzzle_hash(ph))))) == 3
            assert len(await client.get_coin_records_by_puzzle_hashes(
                [ph_receiver, ph])) == 5
            assert len(await
                       client.get_coin_records_by_puzzle_hash(ph, False)) == 3
            assert len(await client.get_coin_records_by_puzzle_hash(ph,
                                                                    True)) == 4

            assert len(await client.get_coin_records_by_puzzle_hash(
                ph, True, 0, 100)) == 4
            assert len(await client.get_coin_records_by_puzzle_hash(
                ph, True, 50, 100)) == 0
            assert len(await client.get_coin_records_by_puzzle_hash(
                ph, True, 0, blocks[-1].height + 1)) == 2
            assert len(await
                       client.get_coin_records_by_puzzle_hash(ph, True, 0,
                                                              1)) == 0

            assert len(await client.get_connections()) == 0

            await client.open_connection(self_hostname, server_2._port)

            async def num_connections():
                return len(await client.get_connections())

            await time_out_assert(10, num_connections, 1)
            connections = await client.get_connections()
            assert NodeType(connections[0]["type"]) == NodeType.FULL_NODE.value
            assert len(await client.get_connections(NodeType.FULL_NODE)) == 1
            assert len(await client.get_connections(NodeType.FARMER)) == 0
            await client.close_connection(connections[0]["node_id"])
            await time_out_assert(10, num_connections, 0)

            blocks: List[FullBlock] = await client.get_blocks(0, 5)
            assert len(blocks) == 5

            await full_node_api_1.reorg_from_index_to_new_index(
                ReorgProtocol(2, 55, bytes([0x2] * 32)))
            new_blocks_0: List[FullBlock] = await client.get_blocks(0, 5)
            assert len(new_blocks_0) == 7

            new_blocks: List[FullBlock] = await client.get_blocks(
                0, 5, exclude_reorged=True)
            assert len(new_blocks) == 5
            assert blocks[0].header_hash == new_blocks[0].header_hash
            assert blocks[1].header_hash == new_blocks[1].header_hash
            assert blocks[2].header_hash == new_blocks[2].header_hash
            assert blocks[3].header_hash != new_blocks[3].header_hash

        finally:
            # Checks that the RPC manages to stop the node
            client.close()
            await client.await_closed()
            await rpc_cleanup()
    async def test_wallet_tx_reorg(self, two_wallet_nodes):
        num_blocks = 5
        full_nodes, wallets = two_wallet_nodes
        full_node_api = full_nodes[0]
        fn_server = full_node_api.full_node.server
        wallet_node, server_2 = wallets[0]
        wallet_node: WalletNode = wallet_node
        wallet_node_2, server_3 = wallets[1]
        wallet = wallet_node.wallet_state_manager.main_wallet
        wallet_2 = wallet_node_2.wallet_state_manager.main_wallet

        ph = await wallet.get_new_puzzlehash()
        ph2 = await wallet_2.get_new_puzzlehash()

        await server_2.start_client(PeerInfo(self_hostname, uint16(fn_server._port)), None)
        await server_3.start_client(PeerInfo(self_hostname, uint16(fn_server._port)), None)
        for i in range(0, num_blocks):
            await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph))
        await time_out_assert(5, wallet_node.wallet_state_manager.blockchain.get_peak_height, 5)

        funds = sum(
            [calculate_pool_reward(uint32(i)) + calculate_base_farmer_reward(uint32(i)) for i in range(1, num_blocks)]
        )
        tx = await wallet.generate_signed_transaction(1000, ph2)
        await wallet.push_transaction(tx)
        await full_node_api.full_node.respond_transaction(tx.spend_bundle, tx.name)
        await time_out_assert(5, wallet.get_confirmed_balance, funds)
        for i in range(0, 2):
            await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(32 * b"0"))
        await time_out_assert(5, wallet_2.get_confirmed_balance, 1000)

        await time_out_assert(5, wallet_node.wallet_state_manager.blockchain.get_peak_height, 7)

        await full_node_api.reorg_from_index_to_new_index(ReorgProtocol(uint32(3), uint32(num_blocks + 6), 32 * b"0"))

        funds = sum(
            [
                calculate_pool_reward(uint32(i)) + calculate_base_farmer_reward(uint32(i))
                for i in range(1, num_blocks - 2)
            ]
        )
        await time_out_assert(7, full_node_api.full_node.blockchain.get_peak_height, 10)
        await time_out_assert(7, wallet_node.wallet_state_manager.blockchain.get_peak_height, 10)

        for i in range(0, num_blocks):
            await asyncio.sleep(1)
            await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(32 * b"0"))

        await time_out_assert(15, wallet.get_confirmed_balance, funds - 1000)
        unconfirmed = await wallet_node.wallet_state_manager.tx_store.get_unconfirmed_for_wallet(int(wallet.id()))
        assert len(unconfirmed) == 0
        tx_record = await wallet_node.wallet_state_manager.tx_store.get_transaction_record(tx.name)
        removed = tx_record.removals[0]
        added = tx_record.additions[0]
        added_1 = tx_record.additions[1]
        wallet_coin_record_rem = await wallet_node.wallet_state_manager.coin_store.get_coin_record(removed.name())
        assert wallet_coin_record_rem.spent

        coin_record_full_node = await full_node_api.full_node.coin_store.get_coin_record(removed.name())
        assert coin_record_full_node.spent
        add_1_coin_record_full_node = await full_node_api.full_node.coin_store.get_coin_record(added.name())
        assert add_1_coin_record_full_node is not None
        assert add_1_coin_record_full_node.confirmed_block_index > 0
        add_2_coin_record_full_node = await full_node_api.full_node.coin_store.get_coin_record(added_1.name())
        assert add_2_coin_record_full_node is not None
        assert add_2_coin_record_full_node.confirmed_block_index > 0