Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions chia/_tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -1288,6 +1288,7 @@ async def farmer_harvester_2_simulators_zero_bits_plot_filter(
num_og_plots=0,
num_pool_plots=0,
num_non_keychain_plots=0,
num_v2_plots=0,
config_overrides=config_overrides,
)
for _ in range(2)
Expand Down
75 changes: 28 additions & 47 deletions chia/_tests/core/custom_types/test_proof_of_space.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
from chia.consensus.default_constants import DEFAULT_CONSTANTS
from chia.types.blockchain_format.proof_of_space import (
calculate_prefix_bits,
calculate_required_plot_strength,
check_plot_size,
make_pos,
passes_plot_filter,
Expand Down Expand Up @@ -113,25 +112,23 @@ def b32(key: str) -> bytes32:
id="v2 plot size 0",
pos_challenge=bytes32(b"1" * 32),
plot_size=PlotSize.make_v2(0),
pool_contract_puzzle_hash=bytes32(b"1" * 32),
plot_public_key=G1Element(),
pool_public_key=G1Element(),
expected_error="Plot size is lower than the minimum",
),
ProofOfSpaceCase(
id="v2 plot size 34",
pos_challenge=bytes32(b"1" * 32),
plot_size=PlotSize.make_v2(34),
pool_contract_puzzle_hash=bytes32(b"1" * 32),
plot_public_key=G1Element(),
pool_public_key=G1Element(),
expected_error="Plot size is higher than the maximum",
),
ProofOfSpaceCase(
id="Not passing the plot filter v2",
pos_challenge=b32("3d29ea79d19b3f7e99ebf764ae53697cbe143603909873946af6ab1ece606861"),
pos_challenge=b32("4cfaacbd2782db64d07cf490ca938534adb07dfbd2f92b0e479e2e5b196178db"),
plot_size=PlotSize.make_v2(32),
pool_public_key=g1(
"b6449c2c68df97c19e884427e42ee7350982d4020571ead08732615ff39bd216bfd630b6460784982bec98b49fea79d0"
),
pool_contract_puzzle_hash=bytes32(b"1" * 32),
plot_public_key=g1(
"879526b4e7b616cfd64984d8ad140d0798b048392a6f11e2faf09054ef467ea44dc0dab5e5edb2afdfa850c5c8b629cc"
),
Expand Down Expand Up @@ -161,16 +158,15 @@ def test_verify_and_get_quality_string(caplog: pytest.LogCaptureFixture, case: P
@datacases(
ProofOfSpaceCase(
id="v2 plot are not implemented",
plot_size=PlotSize.make_v2(30),
pos_challenge=b32("47deb938e145d25d7b3b3c85ca9e3972b76c01aeeb78a02fe5d3b040d282317e"),
plot_size=PlotSize.make_v2(28),
pos_challenge=b32("6a85c4c5f21e5728c6668b01c0758e33bb7f3ae20d38703d4863ad151f983d9c"),
plot_public_key=g1(
"afa3aaf09c03885154be49216ee7fb2e4581b9c4a4d7e9cc402e27280bf0cfdbdf1b9ba674e301fd1d1450234b3b1868"
),
pool_public_key=g1(
"b6449c2c68df97c19e884427e42ee7350982d4020571ead08732615ff39bd216bfd630b6460784982bec98b49fea79d0"
),
expected_error="NotImplementedError",
pool_contract_puzzle_hash=bytes32(b"1" * 32),
expected_error="Did not pass the plot filter",
),
# TODO: todo_v2_plots add test case that passes the plot filter
)
def test_verify_and_get_quality_string_v2(caplog: pytest.LogCaptureFixture, case: ProofOfSpaceCase) -> None:
pos = make_pos(
Expand Down Expand Up @@ -200,29 +196,6 @@ def test_verify_and_get_quality_string_v2(caplog: pytest.LogCaptureFixture, case
assert len(caplog.text) == 0 if case.expected_error is None else case.expected_error in caplog.text


@pytest.mark.parametrize(
"height, strength",
[
(0, 2),
(DEFAULT_CONSTANTS.HARD_FORK_HEIGHT, 2),
(DEFAULT_CONSTANTS.HARD_FORK2_HEIGHT, 2),
(DEFAULT_CONSTANTS.PLOT_STRENGTH_4_HEIGHT - 1, 2),
(DEFAULT_CONSTANTS.PLOT_STRENGTH_4_HEIGHT, 4),
(DEFAULT_CONSTANTS.PLOT_STRENGTH_5_HEIGHT - 1, 4),
(DEFAULT_CONSTANTS.PLOT_STRENGTH_5_HEIGHT, 5),
(DEFAULT_CONSTANTS.PLOT_STRENGTH_6_HEIGHT - 1, 5),
(DEFAULT_CONSTANTS.PLOT_STRENGTH_6_HEIGHT, 6),
(DEFAULT_CONSTANTS.PLOT_STRENGTH_7_HEIGHT - 1, 6),
(DEFAULT_CONSTANTS.PLOT_STRENGTH_7_HEIGHT, 7),
(DEFAULT_CONSTANTS.PLOT_STRENGTH_8_HEIGHT - 1, 7),
(DEFAULT_CONSTANTS.PLOT_STRENGTH_8_HEIGHT, 8),
(DEFAULT_CONSTANTS.PLOT_STRENGTH_8_HEIGHT + 1000000, 8),
],
)
def test_calculate_plot_strength(height: uint32, strength: uint8) -> None:
assert calculate_required_plot_strength(DEFAULT_CONSTANTS, height) == strength


@pytest.mark.parametrize(
"size, valid",
[
Expand Down Expand Up @@ -272,12 +245,9 @@ def test_can_create_proof(self, prefix_bits: int, seeded_random: random.Random)


@pytest.mark.parametrize("height,expected", [(0, 3), (5496000, 2), (10542000, 1), (15592000, 0), (20643000, 0)])
@pytest.mark.parametrize("plot_size", [PlotSize.make_v1(32), PlotSize.make_v2(28)])
def test_calculate_prefix_bits_clamp_zero(height: uint32, expected: int, plot_size: PlotSize) -> None:
def test_calculate_prefix_bits_clamp_zero_v1(height: uint32, expected: int) -> None:
constants = DEFAULT_CONSTANTS.replace(NUMBER_ZERO_BITS_PLOT_FILTER_V1=uint8(3))
if plot_size.size_v2 is not None:
expected = constants.NUMBER_ZERO_BITS_PLOT_FILTER_V2
assert calculate_prefix_bits(constants, height, plot_size) == expected
assert calculate_prefix_bits(constants, height, PlotSize.make_v1(32)) == expected


@pytest.mark.parametrize(
Expand All @@ -294,9 +264,20 @@ def test_calculate_prefix_bits_clamp_zero(height: uint32, expected: int, plot_si
(20643000, 5),
],
)
@pytest.mark.parametrize("plot_size", [PlotSize.make_v1(32), PlotSize.make_v2(28)])
def test_calculate_prefix_bits_default(height: uint32, expected: int, plot_size: PlotSize) -> None:
constants = DEFAULT_CONSTANTS
if plot_size.size_v2 is not None:
expected = DEFAULT_CONSTANTS.NUMBER_ZERO_BITS_PLOT_FILTER_V2
assert calculate_prefix_bits(constants, height, plot_size) == expected
def test_calculate_prefix_bits_v1(height: uint32, expected: int) -> None:
assert calculate_prefix_bits(DEFAULT_CONSTANTS, height, PlotSize.make_v1(32)) == expected


@pytest.mark.parametrize(
argnames=["height", "expected"],
argvalues=[
(0, 5),
(0xFFFFFFFA, 5),
(0xFFFFFFFB, 6),
(0xFFFFFFFC, 7),
(0xFFFFFFFD, 8),
(0xFFFFFFFF, 8),
],
)
def test_calculate_prefix_bits_v2(height: uint32, expected: int) -> None:
assert calculate_prefix_bits(DEFAULT_CONSTANTS, height, PlotSize.make_v2(28)) == expected
20 changes: 17 additions & 3 deletions chia/_tests/core/test_farmer_harvester_rpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ async def wait_for_plot_sync() -> bool:
await farmer_api.farmer.update_pool_state()

pool_plot_count: int = (await farmer_rpc_client.get_pool_state())["pool_state"][0]["plot_count"]
assert pool_plot_count == 5
assert pool_plot_count == 20

# TODO: Maybe improve this to not remove from Receiver directly but instead from the harvester and then wait for
# plot sync event.
Expand Down Expand Up @@ -334,8 +334,8 @@ def test_plot_matches_filter(filter_item: FilterItem, match: bool) -> None:
@pytest.mark.parametrize(
"endpoint, filtering, sort_key, reverse, expected_plot_count",
[
(FarmerRpcClient.get_harvester_plots_valid, [], "filename", False, 20),
(FarmerRpcClient.get_harvester_plots_valid, [], "size", True, 20),
(FarmerRpcClient.get_harvester_plots_valid, [], "filename", False, 35),
(FarmerRpcClient.get_harvester_plots_valid, [], "size", True, 35),
(
FarmerRpcClient.get_harvester_plots_valid,
[FilterItem("pool_contract_puzzle_hash", None)],
Expand All @@ -350,6 +350,20 @@ def test_plot_matches_filter(filter_item: FilterItem, match: bool) -> None:
False,
4,
),
(
FarmerRpcClient.get_harvester_plots_valid,
[FilterItem("strength", "2")],
"size",
True,
15,
),
(
FarmerRpcClient.get_harvester_plots_valid,
[FilterItem("strength", "0")],
"size",
True,
20,
),
(FarmerRpcClient.get_harvester_plots_invalid, [], None, True, 13),
(FarmerRpcClient.get_harvester_plots_invalid, ["invalid_0"], None, False, 6),
(FarmerRpcClient.get_harvester_plots_invalid, ["inval", "lid_1"], None, False, 2),
Expand Down
45 changes: 32 additions & 13 deletions chia/_tests/farmer_harvester/test_farmer_harvester.py
Original file line number Diff line number Diff line change
Expand Up @@ -338,9 +338,11 @@ async def test_v2_partial_proofs_new_sp_hash(
challenge_hash=bytes32(b"2" * 32),
sp_hash=sp_hash,
plot_identifier="test_plot_id",
partial_proofs=[b"test_partial_proof_1"],
partial_proofs=[[uint64(1), uint64(2), uint64(3), uint64(4)]],
signage_point_index=uint8(0),
plot_size=uint8(32),
strength=uint8(5),
plot_id=bytes32.fromhex("abababababababababababababababababababababababababababababababab"),
pool_public_key=None,
pool_contract_puzzle_hash=bytes32(b"4" * 32),
plot_public_key=G1Element(),
Expand All @@ -367,9 +369,11 @@ async def test_v2_partial_proofs_missing_sp_hash(
challenge_hash=bytes32(b"2" * 32),
sp_hash=sp_hash,
plot_identifier="test_plot_id",
partial_proofs=[b"test_partial_proof_1"],
partial_proofs=[[uint64(1), uint64(2), uint64(3), uint64(4)]],
signage_point_index=uint8(0),
plot_size=uint8(32),
plot_id=bytes32.fromhex("abababababababababababababababababababababababababababababababab"),
strength=uint8(5),
pool_public_key=None,
pool_contract_puzzle_hash=bytes32(b"4" * 32),
plot_public_key=G1Element(),
Expand Down Expand Up @@ -409,9 +413,11 @@ async def test_v2_partial_proofs_with_existing_sp(
challenge_hash=challenge_hash,
sp_hash=sp_hash,
plot_identifier="test_plot_id",
partial_proofs=[b"test_partial_proof_1", b"test_partial_proof_2"],
partial_proofs=[[uint64(1), uint64(2), uint64(3), uint64(4)], [uint64(2), uint64(3), uint64(4), uint64(5)]],
signage_point_index=uint8(0),
plot_size=uint8(32),
plot_id=bytes32.fromhex("abababababababababababababababababababababababababababababababab"),
strength=uint8(5),
pool_public_key=G1Element(),
pool_contract_puzzle_hash=bytes32(b"4" * 32),
plot_public_key=G1Element(),
Expand Down Expand Up @@ -441,9 +447,11 @@ async def test_solution_response_handler(
challenge_hash=challenge_hash,
sp_hash=sp_hash,
plot_identifier="test_plot_id",
partial_proofs=[b"test_partial_proof_for_quality"],
partial_proofs=[[uint64(1), uint64(2), uint64(3), uint64(4)]],
signage_point_index=uint8(0),
plot_size=uint8(32),
plot_id=bytes32.fromhex("abababababababababababababababababababababababababababababababab"),
strength=uint8(5),
pool_public_key=G1Element(),
pool_contract_puzzle_hash=bytes32(b"4" * 32),
plot_public_key=G1Element(),
Expand All @@ -452,7 +460,8 @@ async def test_solution_response_handler(
harvester_peer = await get_harvester_peer(farmer)

# manually add pending request
farmer.pending_solver_requests[partial_proofs.partial_proofs[0]] = {
key = bytes(partial_proofs.partial_proofs[0])
farmer.pending_solver_requests[key] = {
"proof_data": partial_proofs,
"peer": harvester_peer,
}
Expand All @@ -477,7 +486,8 @@ async def test_solution_response_handler(
assert original_peer == harvester_peer

# verify pending request was removed
assert partial_proofs.partial_proofs[0] not in farmer.pending_solver_requests
key = bytes(partial_proofs.partial_proofs[0])
assert key not in farmer.pending_solver_requests


@pytest.mark.anyio
Expand All @@ -492,7 +502,9 @@ async def test_solution_response_unknown_quality(
solver_peer = await get_solver_peer(farmer)

# create solution response with unknown quality
solution_response = solver_protocol.SolverResponse(partial_proof=bytes(b"1" * 32), proof=b"test_proof")
solution_response = solver_protocol.SolverResponse(
partial_proof=[uint64(1), uint64(2), uint64(3), uint64(4)], proof=b"test_proof"
)

with unittest.mock.patch.object(farmer_api, "new_proof_of_space", new_callable=AsyncMock) as mock_new_proof:
await farmer_api.solution_response(solution_response, solver_peer)
Expand All @@ -518,9 +530,11 @@ async def test_solution_response_empty_proof(
challenge_hash=challenge_hash,
sp_hash=sp_hash,
plot_identifier="test_plot_id",
partial_proofs=[b"test_partial_proof_for_quality"],
partial_proofs=[[uint64(1), uint64(2), uint64(3), uint64(4)], [uint64(2), uint64(3), uint64(4), uint64(5)]],
signage_point_index=uint8(0),
plot_size=uint8(32),
plot_id=bytes32.fromhex("abababababababababababababababababababababababababababababababab"),
strength=uint8(5),
pool_public_key=G1Element(),
pool_contract_puzzle_hash=bytes32(b"4" * 32),
plot_public_key=G1Element(),
Expand All @@ -530,8 +544,9 @@ async def test_solution_response_empty_proof(
harvester_peer.peer_node_id = "harvester_peer"

# manually add pending request
farmer.pending_solver_requests[partial_proofs.partial_proofs[0]] = {
"proof_data": partial_proofs.partial_proofs[0],
key = bytes(partial_proofs.partial_proofs[0])
farmer.pending_solver_requests[key] = {
"proof_data": partial_proofs,
"peer": harvester_peer,
}

Expand All @@ -548,7 +563,8 @@ async def test_solution_response_empty_proof(
mock_new_proof.assert_not_called()

# verify pending request was removed (cleanup still happens)
assert partial_proofs.partial_proofs[0] not in farmer.pending_solver_requests
key = bytes(partial_proofs.partial_proofs[0])
assert key not in farmer.pending_solver_requests


@pytest.mark.anyio
Expand Down Expand Up @@ -579,9 +595,11 @@ async def test_v2_partial_proofs_solver_exception(
challenge_hash=challenge_hash,
sp_hash=sp_hash,
plot_identifier="test_plot_id",
partial_proofs=[b"test_partial_proof_1"],
partial_proofs=[[uint64(1), uint64(2), uint64(3), uint64(4)], [uint64(2), uint64(3), uint64(4), uint64(5)]],
signage_point_index=uint8(0),
plot_size=uint8(32),
plot_id=bytes32.fromhex("abababababababababababababababababababababababababababababababab"),
strength=uint8(5),
pool_public_key=G1Element(),
pool_contract_puzzle_hash=bytes32(b"4" * 32),
plot_public_key=G1Element(),
Expand All @@ -594,4 +612,5 @@ async def test_v2_partial_proofs_solver_exception(
await farmer_api.partial_proofs(partial_proofs, harvester_peer)

# verify pending request was cleaned up after exception
assert partial_proofs.partial_proofs[0] not in farmer.pending_solver_requests
key = bytes(partial_proofs.partial_proofs[0])
assert key not in farmer.pending_solver_requests
15 changes: 11 additions & 4 deletions chia/_tests/harvester/test_harvester_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from chia._tests.plotting.util import get_test_plots
from chia._tests.util.time_out_assert import time_out_assert
from chia.harvester.harvester_api import HarvesterAPI
from chia.plotting.prover import V1Prover, V2Prover
from chia.plotting.util import PlotInfo
from chia.protocols import harvester_protocol
from chia.protocols.harvester_protocol import PoolDifficulty
Expand Down Expand Up @@ -85,10 +86,16 @@ def create_test_setup(

@contextmanager
def mock_successful_proof(plot_info: PlotInfo) -> Iterator[None]:
with patch.object(plot_info.prover, "get_full_proof") as mock_get_proof:
mock_proof = MagicMock(spec=ProofOfSpace)
mock_get_proof.return_value = mock_proof, None
yield
if isinstance(plot_info.prover, V1Prover):
with patch.object(plot_info.prover, "get_full_proof") as mock_get_proof:
mock_proof = MagicMock(spec=ProofOfSpace)
mock_get_proof.return_value = mock_proof, None
yield
elif isinstance(plot_info.prover, V2Prover):
with patch.object(plot_info.prover, "get_partial_proof") as mock_get_proof:
mock_proof = MagicMock(spec=ProofOfSpace)
mock_get_proof.return_value = [uint64(1)] * 64, None
yield


def assert_farming_info_sent(mock_peer: MagicMock) -> None:
Expand Down
1 change: 1 addition & 0 deletions chia/_tests/plot_sync/test_delta.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ def dummy_plot(path: str) -> Plot:
return Plot(
filename=path,
size=uint8(32),
strength=uint8(0),
plot_id=bytes32(b"\00" * 32),
pool_public_key=G1Element(),
pool_contract_puzzle_hash=None,
Expand Down
1 change: 1 addition & 0 deletions chia/_tests/plot_sync/test_plot_sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ def create_mock_plot(info: MockPlotInfo) -> Plot:
return Plot(
info.prover.get_filename(),
uint8(0),
uint8(0),
bytes32.zeros,
None,
None,
Expand Down
1 change: 1 addition & 0 deletions chia/_tests/plot_sync/test_receiver.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ def plot_sync_setup(seeded_random: random.Random) -> tuple[Receiver, list[SyncSt
Plot(
filename=str(x),
size=uint8(0),
strength=uint8(0),
plot_id=bytes32.random(seeded_random),
pool_contract_puzzle_hash=None,
pool_public_key=None,
Expand Down
Loading
Loading