Пример #1
0
    async def test_wallet_make_transaction(self, two_wallet_nodes):
        test_rpc_port = uint16(21529)
        num_blocks = 5
        full_nodes, wallets = two_wallet_nodes
        full_node_1, server_1 = full_nodes[0]
        wallet_node, server_2 = wallets[0]
        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()
        ph_2 = await wallet_2.get_new_puzzlehash()

        await server_2.start_client(
            PeerInfo("localhost", uint16(server_1._port)), None)

        for i in range(0, num_blocks):
            await full_node_1.farm_new_block(FarmNewBlockProtocol(ph))

        initial_funds = sum([
            calculate_base_fee(uint32(i)) + calculate_block_reward(uint32(i))
            for i in range(1, num_blocks - 1)
        ])
        initial_funds_eventually = sum([
            calculate_base_fee(uint32(i)) + calculate_block_reward(uint32(i))
            for i in range(1, num_blocks + 1)
        ])

        wallet_rpc_api = WalletRpcApi(wallet_node)

        config = load_config(bt.root_path, "config.yaml")
        hostname = config["self_hostname"]
        daemon_port = config["daemon_port"]

        def stop_node_cb():
            pass

        rpc_cleanup = await start_rpc_server(
            wallet_rpc_api,
            hostname,
            daemon_port,
            test_rpc_port,
            stop_node_cb,
            connect_to_daemon=False,
        )

        await time_out_assert(5, wallet.get_confirmed_balance, initial_funds)
        await time_out_assert(5, wallet.get_unconfirmed_balance, initial_funds)

        client = await WalletRpcClient.create("localhost", test_rpc_port)
        try:
            addr = encode_puzzle_hash(await wallet_node_2.wallet_state_manager.
                                      main_wallet.get_new_puzzlehash())
            tx_amount = 15600000
            try:
                await client.send_transaction("1", 100000000000000000, addr)
                raise Exception("Should not create high value tx")
            except ValueError:
                pass

            tx = await client.send_transaction("1", tx_amount, addr)
            transaction_id = tx.name()

            async def tx_in_mempool():
                tx = await client.get_transaction("1", transaction_id)
                return tx.is_in_mempool()

            await time_out_assert(5, tx_in_mempool, True)
            await time_out_assert(5, wallet.get_unconfirmed_balance,
                                  initial_funds - tx_amount)
            assert (
                await client.get_wallet_balance("1")
            )["unconfirmed_wallet_balance"] == initial_funds - tx_amount
            assert (await client.get_wallet_balance("1")
                    )["confirmed_wallet_balance"] == initial_funds

            for i in range(0, 5):
                await client.farm_block(encode_puzzle_hash(ph_2))
                await asyncio.sleep(1)

            async def eventual_balance():
                return (
                    await
                    client.get_wallet_balance("1"))["confirmed_wallet_balance"]

            await time_out_assert(5, eventual_balance,
                                  initial_funds_eventually - tx_amount)

            address = await client.get_next_address("1")
            assert len(address) > 10

            transactions = await client.get_transactions("1")
            assert len(transactions) > 1

            pks = await client.get_public_keys()
            assert len(pks) == 1

            assert (await client.get_height_info()) > 0

            sk_dict = await client.get_private_key(pks[0])
            assert sk_dict["fingerprint"] == pks[0]
            assert sk_dict["sk"] is not None
            assert sk_dict["pk"] is not None
            assert sk_dict["seed"] is not None

            mnemonic = await client.generate_mnemonic()
            assert len(mnemonic) == 24

            await client.add_key(mnemonic)

            pks = await client.get_public_keys()
            assert len(pks) == 2

            await client.log_in_and_skip(pks[1])
            sk_dict = await client.get_private_key(pks[1])
            assert sk_dict["fingerprint"] == pks[1]

            await client.delete_key(pks[0])
            await client.log_in_and_skip(pks[1])
            assert len(await client.get_public_keys()) == 1

            assert not (await client.get_sync_status())

            wallets = await client.get_wallets()
            assert len(wallets) == 1
            balance = await client.get_wallet_balance(wallets[0]["id"])
            assert balance["unconfirmed_wallet_balance"] == 0

            test_wallet_backup_path = Path("test_wallet_backup_file")
            await client.create_backup(test_wallet_backup_path)
            assert test_wallet_backup_path.exists()
            test_wallet_backup_path.unlink()

            try:
                await client.send_transaction(wallets[0]["id"], 100, addr)
                raise Exception("Should not create tx if no balance")
            except ValueError:
                pass

            await client.delete_all_keys()

            assert len(await client.get_public_keys()) == 0
        except Exception:
            # Checks that the RPC manages to stop the node
            client.close()
            await client.await_closed()
            await rpc_cleanup()
            raise

        client.close()
        await client.await_closed()
        await rpc_cleanup()
Пример #2
0
    async def test_create_rl_coin(self, three_wallet_nodes):
        num_blocks = 4
        full_nodes, wallets = three_wallet_nodes
        full_node_1, server_1 = full_nodes[0]
        wallet_node, server_2 = wallets[0]
        wallet_node_1, wallet_server_1 = wallets[1]
        wallet_node_2, wallet_server_2 = wallets[2]

        wallet = wallet_node.wallet_state_manager.main_wallet
        ph = await wallet.get_new_puzzlehash()
        await server_2.start_client(
            PeerInfo("localhost", uint16(server_1._port)), None)
        await wallet_server_1.start_client(
            PeerInfo("localhost", uint16(server_1._port)), None)
        await wallet_server_2.start_client(
            PeerInfo("localhost", uint16(server_1._port)), None)
        for i in range(0, num_blocks):
            await full_node_1.farm_new_block(FarmNewBlockProtocol(ph))

        api_user = WalletRpcApi(wallet_node_1)
        val = await api_user.create_new_wallet({
            "wallet_type": "rl_wallet",
            "rl_type": "user"
        })
        assert isinstance(val, dict)
        assert val["success"]
        assert val["id"]
        assert val["type"] == WalletType.RATE_LIMITED.value
        pubkey = val["pubkey"]

        api_admin = WalletRpcApi(wallet_node)
        val = await api_admin.create_new_wallet({
            "wallet_type": "rl_wallet",
            "rl_type": "admin",
            "interval": 2,
            "limit": 1,
            "pubkey": pubkey,
            "amount": 100,
        })
        assert isinstance(val, dict)
        assert val["success"]
        assert val["id"]
        assert val["type"] == WalletType.RATE_LIMITED.value
        assert val["origin"]
        assert val["pubkey"]
        admin_pubkey = val["pubkey"]
        origin: Coin = val["origin"]

        val = await api_user.rl_set_user_info({
            "wallet_id": 2,
            "interval": 2,
            "limit": 1,
            "origin": {
                "parent_coin_info": origin.parent_coin_info.hex(),
                "puzzle_hash": origin.puzzle_hash.hex(),
                "amount": origin.amount,
            },
            "admin_pubkey": admin_pubkey,
        })
        assert val["success"]

        assert (await api_user.get_wallet_balance(
            {"wallet_id":
             2}))["wallet_balance"]["confirmed_wallet_balance"] == 0
        for i in range(0, 2 * num_blocks):
            await full_node_1.farm_new_block(FarmNewBlockProtocol(32 * b"\0"))

        async def check_balance(api, wallet_id):
            balance_response = await api.get_wallet_balance(
                {"wallet_id": wallet_id})
            balance = balance_response["wallet_balance"][
                "confirmed_wallet_balance"]
            return balance

        await time_out_assert(15, check_balance, 100, api_user, 2)
        receiving_wallet = wallet_node_2.wallet_state_manager.main_wallet
        puzzle_hash = encode_puzzle_hash(await
                                         receiving_wallet.get_new_puzzlehash())
        assert await receiving_wallet.get_spendable_balance() == 0
        val = await api_user.send_transaction({
            "wallet_id": 2,
            "amount": 3,
            "fee": 0,
            "puzzle_hash": puzzle_hash
        })

        assert val["status"] == "SUCCESS"
        for i in range(0, 2 * num_blocks):
            await full_node_1.farm_new_block(FarmNewBlockProtocol(32 * b"\0"))
        await time_out_assert(15, check_balance, 97, api_user, 2)
        await time_out_assert(15, receiving_wallet.get_spendable_balance, 3)
Пример #3
0
    async def test_create_rl_coin(self, three_wallet_nodes):
        num_blocks = 4
        full_nodes, wallets = three_wallet_nodes
        full_node_api = full_nodes[0]
        full_node_server = full_node_api.server
        wallet_node, server_2 = wallets[0]
        wallet_node_1, wallet_server_1 = wallets[1]
        wallet_node_2, wallet_server_2 = wallets[2]

        wallet = wallet_node.wallet_state_manager.main_wallet
        ph = await wallet.get_new_puzzlehash()
        await server_2.start_client(PeerInfo(self_hostname, uint16(full_node_server._port)), None)
        await wallet_server_1.start_client(PeerInfo(self_hostname, uint16(full_node_server._port)), None)
        await wallet_server_2.start_client(PeerInfo(self_hostname, uint16(full_node_server._port)), None)
        await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph))
        for i in range(0, num_blocks + 1):
            await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(32 * b"\0"))
        fund_owners_initial_balance = await wallet.get_confirmed_balance()

        api_user = WalletRpcApi(wallet_node_1)
        val = await api_user.create_new_wallet(
            {"wallet_type": "rl_wallet", "rl_type": "user", "host": f"{self_hostname}:5000"}
        )
        assert isinstance(val, dict)
        if "success" in val:
            assert val["success"]
        assert val["id"]
        assert val["type"] == WalletType.RATE_LIMITED.value
        user_wallet_id = val["id"]
        pubkey = val["pubkey"]

        api_admin = WalletRpcApi(wallet_node)
        val = await api_admin.create_new_wallet(
            {
                "wallet_type": "rl_wallet",
                "rl_type": "admin",
                "interval": 2,
                "limit": 10,
                "pubkey": pubkey,
                "amount": 100,
                "fee": 1,
                "host": f"{self_hostname}:5000",
            }
        )
        assert isinstance(val, dict)
        if "success" in val:
            assert val["success"]
        assert val["id"]
        assert val["type"] == WalletType.RATE_LIMITED.value
        assert val["origin"]
        assert val["pubkey"]
        admin_wallet_id = val["id"]
        admin_pubkey = val["pubkey"]
        origin: Coin = val["origin"]

        await api_user.rl_set_user_info(
            {
                "wallet_id": user_wallet_id,
                "interval": 2,
                "limit": 10,
                "origin": {
                    "parent_coin_info": origin.parent_coin_info.hex(),
                    "puzzle_hash": origin.puzzle_hash.hex(),
                    "amount": origin.amount,
                },
                "admin_pubkey": admin_pubkey,
            }
        )

        assert (await api_user.get_wallet_balance({"wallet_id": user_wallet_id}))["wallet_balance"][
            "confirmed_wallet_balance"
        ] == 0
        for i in range(0, 2 * num_blocks):
            await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(32 * b"\0"))

        assert await wallet.get_confirmed_balance() == fund_owners_initial_balance - 101

        async def check_balance(api, wallet_id):
            balance_response = await api.get_wallet_balance({"wallet_id": wallet_id})
            balance = balance_response["wallet_balance"]["confirmed_wallet_balance"]
            return balance

        await time_out_assert(15, check_balance, 100, api_user, user_wallet_id)
        receiving_wallet = wallet_node_2.wallet_state_manager.main_wallet
        address = encode_puzzle_hash(await receiving_wallet.get_new_puzzlehash(), "xch")
        assert await receiving_wallet.get_spendable_balance() == 0
        val = await api_user.send_transaction({"wallet_id": user_wallet_id, "amount": 3, "fee": 2, "address": address})
        assert "transaction_id" in val

        async def is_transaction_in_mempool(api, tx_id: bytes32) -> bool:
            try:
                val = await api.get_transaction({"wallet_id": user_wallet_id, "transaction_id": tx_id.hex()})
            except ValueError:
                return False
            for _, mis, _ in val["transaction"].sent_to:
                if (
                    MempoolInclusionStatus(mis) == MempoolInclusionStatus.SUCCESS
                    or MempoolInclusionStatus(mis) == MempoolInclusionStatus.PENDING
                ):
                    return True
            return False

        await time_out_assert(15, is_transaction_in_mempool, True, api_user, val["transaction_id"])

        for i in range(0, num_blocks):
            await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(32 * b"\0"))
        await time_out_assert(15, check_balance, 95, api_user, user_wallet_id)
        await time_out_assert(15, receiving_wallet.get_spendable_balance, 3)
        val = await api_admin.add_rate_limited_funds({"wallet_id": admin_wallet_id, "amount": 100, "fee": 7})
        assert val["status"] == "SUCCESS"
        for i in range(0, 50):
            await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(32 * b"\0"))
        await time_out_assert(15, check_balance, 195, api_user, user_wallet_id)

        # test spending
        puzzle_hash = encode_puzzle_hash(await receiving_wallet.get_new_puzzlehash(), "xch")
        val = await api_user.send_transaction(
            {
                "wallet_id": user_wallet_id,
                "amount": 105,
                "fee": 0,
                "address": puzzle_hash,
            }
        )
        await time_out_assert(15, is_transaction_in_mempool, True, api_user, val["transaction_id"])
        for i in range(0, num_blocks):
            await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(32 * b"\0"))
        await time_out_assert(15, check_balance, 90, api_user, user_wallet_id)
        await time_out_assert(15, receiving_wallet.get_spendable_balance, 108)

        val = await api_admin.send_clawback_transaction({"wallet_id": admin_wallet_id, "fee": 11})
        await time_out_assert(15, is_transaction_in_mempool, True, api_admin, val["transaction_id"])
        for i in range(0, num_blocks):
            await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(32 * b"\0"))
        await time_out_assert(15, check_balance, 0, api_user, user_wallet_id)
        await time_out_assert(15, check_balance, 0, api_admin, user_wallet_id)
        final_balance = await wallet.get_confirmed_balance()
        assert final_balance == fund_owners_initial_balance - 129