Skip to content

Commit

Permalink
CHIA-1730: port chia plotnft to @chia_commands framework (#18833)
Browse files Browse the repository at this point in the history
* chia plotnft CLI improvements

* use CliRpcConnectionError

* add check to show

* fix typo

* Update plotnft CLI to newer framework

* Fix help cut-paste error

* add test using new framework

* some minor fixes

* use click.Choice for pool/local option

* some click options

* Some more plotnft cli tests

* drop test_pool_cmdline from mypy-exclusions

* mypy fixes

* several fixes

* Add leave test

* join tests

* more join tests

* missing await

* Try setting config

* use root_path from NeedsWalletRPC

* linting

* Some cleanup

* Add claim tests

* Improved tests

* refactor some test code

* Add inspect tests

* Skip bad test for now

* Add in change payout tests

* quoting error

* Add test for get_login_link

* Add in a few negative tests for join

* Few more tests

* Experment with clirunner env overrides

* put back chia_root into context dict

* Some cleanup and one more test

* maybe final test

* some updates

* some dedup and reorg of test code

* run trusted and untrusted paramertization

* make reuse puzhash stuff work

* Add in required mock object for test_update_pool_config_new_config

* rearrange code per review comment - limit use of NeedsWalletRPC to chia_command

* Add in plotnft click parsing tests

* added ability to pass in obj to runner invoke

* Add in some more test cases

* fix up create issues with config

* Add in couple more test cases for error conditions

* Minor code cleanup

* Use long options for readability, minor code cleanup

* Use config file for farmer rpc port

* simplify code

* Add testing for prompt cases

* Add mocking for default_root_path

* context cleanup

* temp debugging output

* patch the proper object

* move some wallet fixtures into top level conftest and remove conftest import

* merge to origin/main
  • Loading branch information
emlowe authored Dec 3, 2024
1 parent 6458663 commit 7c01e3c
Show file tree
Hide file tree
Showing 10 changed files with 1,745 additions and 335 deletions.
4 changes: 2 additions & 2 deletions chia/_tests/cmds/test_cmd_framework.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
from chia.types.blockchain_format.sized_bytes import bytes32


def check_click_parsing(cmd: ChiaCommand, *args: str) -> None:
def check_click_parsing(cmd: ChiaCommand, *args: str, obj: Optional[Any] = None) -> None:
@click.group()
def _cmd() -> None:
pass
Expand All @@ -40,7 +40,7 @@ def new_run(self: Any) -> None:
chia_command(_cmd, "_", "", "")(mock_type)

runner = CliRunner()
result = runner.invoke(_cmd, ["_", *args], catch_exceptions=False)
result = runner.invoke(_cmd, ["_", *args], catch_exceptions=False, obj=obj)
assert result.output == ""


Expand Down
124 changes: 124 additions & 0 deletions chia/_tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,18 @@

multiprocessing.set_start_method("spawn")

from dataclasses import replace
from pathlib import Path

from chia._tests.environments.wallet import WalletEnvironment, WalletState, WalletTestFramework
from chia._tests.util.setup_nodes import setup_farmer_multi_harvester
from chia.rpc.full_node_rpc_client import FullNodeRpcClient
from chia.simulator.block_tools import BlockTools, create_block_tools_async, test_constants
from chia.simulator.keyring import TempKeyring
from chia.util.ints import uint128
from chia.util.keyring_wrapper import KeyringWrapper
from chia.wallet.util.tx_config import DEFAULT_TX_CONFIG, TXConfig
from chia.wallet.wallet_node import Balance


@pytest.fixture(name="ether_setup", autouse=True)
Expand Down Expand Up @@ -1293,3 +1299,121 @@ async def recording_web_server_fixture(self_hostname: str) -> AsyncIterator[Reco
)
def use_delta_sync(request: SubRequest):
return request.param


# originally from _tests/wallet/conftest.py
@pytest.fixture(scope="function", params=[True, False])
def trusted_full_node(request: Any) -> bool:
trusted: bool = request.param
return trusted


@pytest.fixture(scope="function", params=[True, False])
def tx_config(request: Any) -> TXConfig:
return replace(DEFAULT_TX_CONFIG, reuse_puzhash=request.param)


# This fixture automatically creates 4 parametrized tests trusted/untrusted x reuse/new derivations
# These parameterizations can be skipped by manually specifying "trusted" or "reuse puzhash" to the fixture
@pytest.fixture(scope="function")
async def wallet_environments(
trusted_full_node: bool,
tx_config: TXConfig,
blockchain_constants: ConsensusConstants,
request: pytest.FixtureRequest,
) -> AsyncIterator[WalletTestFramework]:
if "trusted" in request.param:
if request.param["trusted"] != trusted_full_node:
pytest.skip("Skipping not specified trusted mode")
if "reuse_puzhash" in request.param:
if request.param["reuse_puzhash"] != tx_config.reuse_puzhash:
pytest.skip("Skipping not specified reuse_puzhash mode")
assert len(request.param["blocks_needed"]) == request.param["num_environments"]
if "config_overrides" in request.param:
config_overrides: dict[str, Any] = request.param["config_overrides"]
else: # pragma: no cover
config_overrides = {}
async with setup_simulators_and_wallets_service(
1,
request.param["num_environments"],
blockchain_constants,
initial_num_public_keys=config_overrides.get("initial_num_public_keys", 5),
) as wallet_nodes_services:
full_node, wallet_services, bt = wallet_nodes_services

full_node[0]._api.full_node.config = {**full_node[0]._api.full_node.config, **config_overrides}

wallet_rpc_clients: list[WalletRpcClient] = []
async with AsyncExitStack() as astack:
for service in wallet_services:
service._node.config = {
**service._node.config,
"trusted_peers": (
{full_node[0]._api.server.node_id.hex(): full_node[0]._api.server.node_id.hex()}
if trusted_full_node
else {}
),
**config_overrides,
}
service._node.wallet_state_manager.config = service._node.config
# Shorten the 10 seconds default value
service._node.coin_state_retry_seconds = 2
await service._node.server.start_client(
PeerInfo(bt.config["self_hostname"], full_node[0]._api.full_node.server.get_port()), None
)
wallet_rpc_clients.append(
await astack.enter_async_context(
WalletRpcClient.create_as_context(
bt.config["self_hostname"],
# Semantics guarantee us a non-None value here
service.rpc_server.listen_port, # type: ignore[union-attr]
service.root_path,
service.config,
)
)
)

wallet_states: list[WalletState] = []
for service, blocks_needed in zip(wallet_services, request.param["blocks_needed"]):
if blocks_needed > 0:
await full_node[0]._api.farm_blocks_to_wallet(
count=blocks_needed, wallet=service._node.wallet_state_manager.main_wallet
)
await full_node[0]._api.wait_for_wallet_synced(wallet_node=service._node, timeout=20)
wallet_states.append(
WalletState(
Balance(
confirmed_wallet_balance=uint128(2_000_000_000_000 * blocks_needed),
unconfirmed_wallet_balance=uint128(2_000_000_000_000 * blocks_needed),
spendable_balance=uint128(2_000_000_000_000 * blocks_needed),
pending_change=uint64(0),
max_send_amount=uint128(2_000_000_000_000 * blocks_needed),
unspent_coin_count=uint32(2 * blocks_needed),
pending_coin_removal_count=uint32(0),
),
)
)

assert full_node[0].rpc_server is not None
client_node = await astack.enter_async_context(
FullNodeRpcClient.create_as_context(
bt.config["self_hostname"],
full_node[0].rpc_server.listen_port,
full_node[0].root_path,
full_node[0].config,
)
)
yield WalletTestFramework(
full_node[0]._api,
client_node,
trusted_full_node,
[
WalletEnvironment(
service=service,
rpc_client=rpc_client,
wallet_states={uint32(1): wallet_state},
)
for service, rpc_client, wallet_state in zip(wallet_services, wallet_rpc_clients, wallet_states)
],
tx_config,
)
128 changes: 128 additions & 0 deletions chia/_tests/pools/test_pool_cli_parsing.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
from __future__ import annotations

from chia._tests.cmds.test_cmd_framework import check_click_parsing
from chia.cmds.cmd_classes import NeedsWalletRPC
from chia.cmds.param_types import CliAddress
from chia.cmds.plotnft import (
ChangePayoutInstructionsPlotNFTCMD,
ClaimPlotNFTCMD,
CreatePlotNFTCMD,
GetLoginLinkCMD,
InspectPlotNFTCMD,
JoinPlotNFTCMD,
LeavePlotNFTCMD,
ShowPlotNFTCMD,
)
from chia.types.blockchain_format.sized_bytes import bytes32
from chia.util.bech32m import encode_puzzle_hash
from chia.util.ints import uint64
from chia.wallet.util.address_type import AddressType


def test_plotnft_command_default_parsing() -> None:
launcher_id = bytes32([1] * 32)
check_click_parsing(
GetLoginLinkCMD(context=dict(), launcher_id=launcher_id),
"--launcher_id",
launcher_id.hex(),
)

burn_ph = bytes32.from_hexstr("0x000000000000000000000000000000000000000000000000000000000000dead")
burn_address = encode_puzzle_hash(burn_ph, "xch")
check_click_parsing(
ChangePayoutInstructionsPlotNFTCMD(
launcher_id=launcher_id, address=CliAddress(burn_ph, burn_address, AddressType.XCH)
),
"--launcher_id",
launcher_id.hex(),
"--address",
burn_address,
obj={"expected_prefix": "xch"}, # Needed for AddressParamType to work correctly without config
)

check_click_parsing(
ClaimPlotNFTCMD(
rpc_info=NeedsWalletRPC(client_info=None, wallet_rpc_port=None, fingerprint=None), fee=uint64(1), id=5
),
"--id",
"5",
"--fee",
"0.000000000001",
)

check_click_parsing(
CreatePlotNFTCMD(
rpc_info=NeedsWalletRPC(client_info=None, wallet_rpc_port=None, fingerprint=None),
pool_url="http://localhost:1234",
state="pool",
fee=uint64(0),
dont_prompt=False,
),
"--state",
"pool",
"--pool-url",
"http://localhost:1234",
"--fee",
"0.0",
)

check_click_parsing(
CreatePlotNFTCMD(
rpc_info=NeedsWalletRPC(client_info=None, wallet_rpc_port=None, fingerprint=None),
pool_url=None,
state="local",
fee=uint64(0),
dont_prompt=True,
),
"--state",
"local",
"-y",
)

check_click_parsing(
InspectPlotNFTCMD(
rpc_info=NeedsWalletRPC(client_info=None, wallet_rpc_port=None, fingerprint=None),
id=5,
),
"--id",
"5",
)

check_click_parsing(
JoinPlotNFTCMD(
rpc_info=NeedsWalletRPC(client_info=None, wallet_rpc_port=None, fingerprint=None),
id=5,
fee=uint64(3),
pool_url="http://localhost:1234",
dont_prompt=True,
),
"--id",
"5",
"--fee",
"0.000000000003",
"--pool-url",
"http://localhost:1234",
"-y",
)

check_click_parsing(
LeavePlotNFTCMD(
rpc_info=NeedsWalletRPC(client_info=None, wallet_rpc_port=None, fingerprint=None),
id=5,
fee=uint64(3),
dont_prompt=True,
),
"--id",
"5",
"--fee",
"0.000000000003",
"-y",
)

check_click_parsing(
ShowPlotNFTCMD(
context=dict(), rpc_info=NeedsWalletRPC(client_info=None, wallet_rpc_port=None, fingerprint=None), id=5
),
"--id",
"5",
)
Loading

0 comments on commit 7c01e3c

Please sign in to comment.