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
21 changes: 9 additions & 12 deletions chia/_tests/core/custom_types/test_proof_of_space.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,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 (0) is lower than the minimum (28)",
),
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 (34) is higher than the maximum (32)",
),
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 @@ -160,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
22 changes: 18 additions & 4 deletions chia/_tests/core/test_farmer_harvester_rpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ async def non_zero_plots() -> bool:
res = await harvester_rpc_client.get_plots()
nonlocal harvester_plots
harvester_plots = res["plots"]
return len(harvester_plots) > 0
return len(harvester_plots) == 340

await time_out_assert(10, non_zero_plots)

Expand Down Expand Up @@ -293,7 +293,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 == 325

# 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 @@ -333,8 +333,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, 340),
(FarmerRpcClient.get_harvester_plots_valid, [], "size", True, 340),
(
FarmerRpcClient.get_harvester_plots_valid,
[FilterItem("pool_contract_puzzle_hash", None)],
Expand All @@ -349,6 +349,20 @@ def test_plot_matches_filter(filter_item: FilterItem, match: bool) -> None:
False,
4,
),
(
FarmerRpcClient.get_harvester_plots_valid,
[FilterItem("strength", "2")],
"size",
True,
320,
),
(
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
11 changes: 6 additions & 5 deletions chia/_tests/farmer_harvester/test_farmer_harvester.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from chia._tests.util.time_out_assert import time_out_assert
from chia.cmds.cmds_util import get_any_service_client
from chia.farmer.farmer import Farmer
from chia.farmer.farmer_api import serialize
from chia.farmer.farmer_service import FarmerService
from chia.harvester.harvester_rpc_client import HarvesterRpcClient
from chia.harvester.harvester_service import HarvesterService
Expand Down Expand Up @@ -460,7 +461,7 @@ async def test_solution_response_handler(
harvester_peer = await get_harvester_peer(farmer)

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

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


Expand Down Expand Up @@ -544,7 +545,7 @@ async def test_solution_response_empty_proof(
harvester_peer.peer_node_id = "harvester_peer"

# manually add pending request
key = bytes(partial_proofs.partial_proofs[0])
key = serialize(partial_proofs.partial_proofs[0])
farmer.pending_solver_requests[key] = {
"proof_data": partial_proofs,
"peer": harvester_peer,
Expand All @@ -563,7 +564,7 @@ async def test_solution_response_empty_proof(
mock_new_proof.assert_not_called()

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


Expand Down Expand Up @@ -612,5 +613,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
key = bytes(partial_proofs.partial_proofs[0])
key = serialize(partial_proofs.partial_proofs[0])
assert key not in farmer.pending_solver_requests
2 changes: 1 addition & 1 deletion chia/_tests/farmer_harvester/test_filter_prefix_bits.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ async def have_connections() -> bool:
await harvester_rpc_cl.await_closed()


@pytest.mark.parametrize(argnames=["peak_height", "eligible_plots"], argvalues=[(5495999, 0), (5496000, 1)])
@pytest.mark.parametrize(argnames=["peak_height", "eligible_plots"], argvalues=[(5495999, 9), (5496000, 10)])
@pytest.mark.anyio
async def test_filter_prefix_bits_with_farmer_harvester(
farmer_harvester_with_filter_size_9: tuple[HarvesterService, FarmerAPI],
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
1 change: 1 addition & 0 deletions chia/_tests/util/network_protocol_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -918,6 +918,7 @@
plot = harvester_protocol.Plot(
"plot_1",
uint8(124),
uint8(0),
bytes32(bytes.fromhex("b2eb7e5c5239e8610a9dd0e137e185966ebb430faf31ae4a0e55d86251065b98")),
G1Element.from_bytes(
bytes.fromhex(
Expand Down
Binary file modified chia/_tests/util/protocol_messages_bytes-v1.0
Binary file not shown.
2 changes: 2 additions & 0 deletions chia/_tests/util/protocol_messages_json.py
Original file line number Diff line number Diff line change
Expand Up @@ -2297,6 +2297,7 @@
plot_json: dict[str, Any] = {
"filename": "plot_1",
"size": 124,
"strength": 0,
"plot_id": "0xb2eb7e5c5239e8610a9dd0e137e185966ebb430faf31ae4a0e55d86251065b98",
"pool_public_key": "0xa04c6b5ac7dfb935f6feecfdd72348ccf1d4be4fe7e26acf271ea3b7d308da61e0a308f7a62495328a81f5147b66634c",
"pool_contract_puzzle_hash": "0x1c96d26def7be696f12e7ebb91d50211e6217ce5d9087c9cd1b84782d5d4b237",
Expand All @@ -2313,6 +2314,7 @@
{
"filename": "plot_1",
"size": 124,
"strength": 0,
"plot_id": "0xb2eb7e5c5239e8610a9dd0e137e185966ebb430faf31ae4a0e55d86251065b98",
"pool_public_key": "0xa04c6b5ac7dfb935f6feecfdd72348ccf1d4be4fe7e26acf271ea3b7d308da61e0a308f7a62495328a81f5147b66634c",
"pool_contract_puzzle_hash": "0x1c96d26def7be696f12e7ebb91d50211e6217ce5d9087c9cd1b84782d5d4b237",
Expand Down
11 changes: 9 additions & 2 deletions chia/farmer/farmer_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,13 @@
)


def serialize(partial_proof: list[uint64]) -> bytes:
key = bytearray()
for val in partial_proof:
key += val.stream_to_bytes()
return bytes(key)


class FarmerAPI:
if TYPE_CHECKING:
from chia.server.api_protocol import ApiProtocol
Expand Down Expand Up @@ -514,7 +521,7 @@ async def partial_proofs(self, partial_proof_data: PartialProofsData, peer: WSCh
size=partial_proof_data.plot_size,
)

key = bytes(partial_proof)
key = serialize(partial_proof)
try:
# store pending request data for matching with response
self.farmer.pending_solver_requests[key] = {
Expand Down Expand Up @@ -543,7 +550,7 @@ async def solution_response(self, response: SolverResponse, peer: WSChiaConnecti

# find the matching pending request using partial_proof

key = bytes(response.partial_proof)
key = serialize(response.partial_proof)
if key not in self.farmer.pending_solver_requests:
self.farmer.log.warning(f"Received solver response for unknown partial proof {response.partial_proof[:5]}")
return
Expand Down
4 changes: 3 additions & 1 deletion chia/harvester/harvester.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,14 +193,16 @@ def get_plots(self) -> tuple[list[dict[str, Any]], list[str], list[str]]:
size = prover.get_size()
if size.size_v1 is not None:
k = size.size_v1
strength = 0
else:
assert size.size_v2 is not None
k = size.size_v2
# TODO: todo_v2_plots support v2 plots in RPC response
strength = prover.get_strength()
response_plots.append(
{
"filename": str(path),
"size": k,
"strength": strength,
"plot_id": prover.get_id(),
"pool_public_key": plot_info.pool_public_key,
"pool_contract_puzzle_hash": plot_info.pool_contract_puzzle_hash,
Expand Down
1 change: 1 addition & 0 deletions chia/harvester/harvester_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,7 @@ async def request_plots(self, _: harvester_protocol.RequestPlots) -> Message:
Plot(
plot["filename"],
plot["size"],
plot["strength"],
plot["plot_id"],
plot["pool_public_key"],
plot["pool_contract_puzzle_hash"],
Expand Down
24 changes: 14 additions & 10 deletions chia/plot_sync/receiver.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,8 @@ def __init__(
async def trigger_callback(self, update: Optional[Delta] = None) -> None:
try:
await self._update_callback(self._connection.peer_node_id, update)
except Exception as e:
log.error(f"_update_callback: node_id {self.connection().peer_node_id}, raised {e}")
except Exception:
log.exception(f"_update_callback: node_id {self.connection().peer_node_id}")

def reset(self) -> None:
log.info(f"reset: node_id {self.connection().peer_node_id}, current_sync: {self._current_sync}")
Expand Down Expand Up @@ -181,13 +181,13 @@ async def send_response(plot_sync_error: Optional[PlotSyncError] = None) -> None
await method(message)
await send_response()
except InvalidIdentifierError as e:
log.warning(f"_process: node_id {self.connection().peer_node_id}, InvalidIdentifierError {e}")
log.exception(f"_process: node_id {self.connection().peer_node_id}")
await send_response(PlotSyncError(int16(e.error_code), f"{e}", e.expected_identifier))
except PlotSyncException as e:
log.warning(f"_process: node_id {self.connection().peer_node_id}, Error {e}")
log.exception(f"_process: node_id {self.connection().peer_node_id}")
await send_response(PlotSyncError(int16(e.error_code), f"{e}", None))
except Exception as e:
log.warning(f"_process: node_id {self.connection().peer_node_id}, Exception {e}")
log.exception(f"_process: node_id {self.connection().peer_node_id}")
await send_response(PlotSyncError(int16(ErrorCodes.unknown), f"{e}", None))

def _validate_identifier(self, identifier: PlotSyncIdentifier, start: bool = False) -> None:
Expand Down Expand Up @@ -349,12 +349,16 @@ async def _sync_done(self, data: PlotSyncDone) -> None:
self._keys_missing = self._current_sync.delta.keys_missing.additions.copy()
self._duplicates = self._current_sync.delta.duplicates.additions.copy()
self._total_plot_size = sum(plot.file_size for plot in self._plots.values())

def expected_plot_size(pi: Plot) -> int:
if pi.strength == 0:
plot_size = PlotSize.make_v1(pi.size)
else:
plot_size = PlotSize.make_v2(pi.size)
return int(_expected_plot_size(plot_size))

self._total_effective_plot_size = int(
# TODO: todo_v2_plots support v2 plots
sum(
UI_ACTUAL_SPACE_CONSTANT_FACTOR * int(_expected_plot_size(PlotSize.make_v1(plot.size)))
for plot in self._plots.values()
)
sum(UI_ACTUAL_SPACE_CONSTANT_FACTOR * expected_plot_size(plot) for plot in self._plots.values())
)
# Save current sync as last sync and create a new current sync
self._last_sync = self._current_sync
Expand Down
20 changes: 15 additions & 5 deletions chia/plot_sync/sender.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from pathlib import Path
from typing import Any, Generic, Optional, TypeVar

from chia_rs.sized_ints import int16, uint32, uint64
from chia_rs.sized_ints import int16, uint8, uint32, uint64
from typing_extensions import Protocol

from chia.plot_sync.exceptions import AlreadyStartedError, InvalidConnectionTypeError
Expand Down Expand Up @@ -37,13 +37,23 @@
def _convert_plot_info_list(plot_infos: list[PlotInfo]) -> list[Plot]:
converted: list[Plot] = []
for plot_info in plot_infos:
# TODO: todo_v2_plots support v2 plots
k = plot_info.prover.get_size().size_v1
assert k is not None
plot_size = plot_info.prover.get_size()
if plot_size.size_v1 is not None:
k = plot_size.size_v1
strength = 0
else:
# todo_v2_plots the k-size should probably be set to the constant,
# fixed k-size for v2 plots. Then we would need access to
# ConsensusConstants in here.
assert plot_size.size_v2 is not None
k = plot_size.size_v2
strength = plot_info.prover.get_strength()

converted.append(
Plot(
filename=plot_info.prover.get_filename(),
size=k,
size=uint8(k),
strength=uint8(strength),
plot_id=plot_info.prover.get_id(),
pool_public_key=plot_info.pool_public_key,
pool_contract_puzzle_hash=plot_info.pool_contract_puzzle_hash,
Expand Down
Loading
Loading