Skip to content

Commit 18fd65d

Browse files
authored
pass along plot format version from ProverProtocol into ProofOfSpace (#19930)
pass along plot format version from ProverProtocol into ProofOfSpace objects
1 parent 45d8ecd commit 18fd65d

File tree

19 files changed

+221
-99
lines changed

19 files changed

+221
-99
lines changed

chia/_tests/core/consensus/test_pot_iterations.py

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ def test_calculate_ip_iters(self):
8383
assert ip_iters == (sp_iters + test_constants.NUM_SP_INTERVALS_EXTRA * sp_interval_iters + required_iters) % ssi
8484
assert sp_iters > ip_iters
8585

86+
# TODO: todo_v2_plots test this for v2 plots as well
8687
def test_win_percentage(self):
8788
"""
8889
Tests that the percentage of blocks won is proportional to the space of each farmer,
@@ -95,7 +96,7 @@ def test_win_percentage(self):
9596
uint8(35): 100,
9697
uint8(36): 100,
9798
}
98-
farmer_space = {k: _expected_plot_size(uint8(k)) * count for k, count in farmer_ks.items()}
99+
farmer_space = {k: _expected_plot_size(PlotSize.make_v1(k)) * count for k, count in farmer_ks.items()}
99100
total_space = sum(farmer_space.values())
100101
percentage_space = {k: float(sp / total_space) for k, sp in farmer_space.items()}
101102
wins = {k: 0 for k in farmer_ks.keys()}
@@ -111,7 +112,6 @@ def test_win_percentage(self):
111112
for k, count in farmer_ks.items():
112113
for farmer_index in range(count):
113114
quality = std_hash(slot_index.to_bytes(4, "big") + k.to_bytes(1, "big") + bytes(farmer_index))
114-
# TODO: todo_v2_plots
115115
required_iters = calculate_iterations_quality(
116116
constants, quality, PlotSize.make_v1(k), difficulty, sp_hash, uint64(100000000), uint32(0)
117117
)
@@ -151,3 +151,24 @@ def test_calculate_phase_out(self):
151151
max_uint32_height = uint32(0xFFFFFFFF)
152152
result_max_height = calculate_phase_out(constants, sub_slot_iters, max_uint32_height)
153153
assert result_max_height == sp_interval # Should cap at sp_interval
154+
155+
156+
def test_expected_plot_size_v1() -> None:
157+
last_size = 4800000
158+
for k in range(18, 50):
159+
plot_size = _expected_plot_size(PlotSize.make_v1(k))
160+
assert plot_size > last_size
161+
last_size = plot_size
162+
163+
164+
def test_expected_plot_size_v2() -> None:
165+
last_size = 1700000000
166+
for k in range(18, 32, 2):
167+
plot_size = _expected_plot_size(PlotSize.make_v2(k))
168+
# TODO: todo_v2_plots remove this special case once we support smaller k-sizes
169+
if k < 28:
170+
assert plot_size == 0
171+
continue
172+
173+
assert plot_size > last_size
174+
last_size = plot_size

chia/_tests/core/custom_types/test_proof_of_space.py

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from typing import Optional
66

77
import pytest
8-
from chia_rs import G1Element, PlotSize, ProofOfSpace
8+
from chia_rs import G1Element, PlotSize
99
from chia_rs.sized_bytes import bytes32, bytes48
1010
from chia_rs.sized_ints import uint8, uint32
1111

@@ -15,6 +15,7 @@
1515
calculate_plot_difficulty,
1616
calculate_prefix_bits,
1717
check_plot_size,
18+
make_pos,
1819
passes_plot_filter,
1920
verify_and_get_quality_string,
2021
)
@@ -24,7 +25,7 @@
2425
class ProofOfSpaceCase:
2526
id: str
2627
pos_challenge: bytes32
27-
plot_size: uint8
28+
plot_size: PlotSize
2829
plot_public_key: G1Element
2930
pool_public_key: Optional[G1Element] = None
3031
pool_contract_puzzle_hash: Optional[bytes32] = None
@@ -46,14 +47,14 @@ def b32(key: str) -> bytes32:
4647
ProofOfSpaceCase(
4748
id="Neither pool public key nor pool contract puzzle hash",
4849
pos_challenge=bytes32(b"1" * 32),
49-
plot_size=uint8(0),
50+
plot_size=PlotSize.make_v1(0),
5051
plot_public_key=G1Element(),
5152
expected_error="Expected pool public key or pool contract puzzle hash but got neither",
5253
),
5354
ProofOfSpaceCase(
5455
id="Both pool public key and pool contract puzzle hash",
5556
pos_challenge=bytes32(b"1" * 32),
56-
plot_size=uint8(0),
57+
plot_size=PlotSize.make_v1(0),
5758
plot_public_key=G1Element(),
5859
pool_public_key=G1Element(),
5960
pool_contract_puzzle_hash=bytes32(b"1" * 32),
@@ -62,31 +63,31 @@ def b32(key: str) -> bytes32:
6263
ProofOfSpaceCase(
6364
id="Lower than minimum plot size",
6465
pos_challenge=bytes32(b"1" * 32),
65-
plot_size=uint8(31),
66+
plot_size=PlotSize.make_v1(31),
6667
plot_public_key=G1Element(),
6768
pool_public_key=G1Element(),
6869
expected_error="Plot size is lower than the minimum",
6970
),
7071
ProofOfSpaceCase(
7172
id="Higher than maximum plot size",
7273
pos_challenge=bytes32(b"1" * 32),
73-
plot_size=uint8(51),
74+
plot_size=PlotSize.make_v1(51),
7475
plot_public_key=G1Element(),
7576
pool_public_key=G1Element(),
7677
expected_error="Plot size is higher than the maximum",
7778
),
7879
ProofOfSpaceCase(
7980
id="Different challenge",
8081
pos_challenge=bytes32(b"1" * 32),
81-
plot_size=uint8(42),
82+
plot_size=PlotSize.make_v1(42),
8283
pool_public_key=G1Element(),
8384
plot_public_key=G1Element(),
8485
expected_error="Calculated pos challenge doesn't match the provided one",
8586
),
8687
ProofOfSpaceCase(
8788
id="Not passing the plot filter with size 9",
8889
pos_challenge=b32("08b23cc2844dfb92d2eedaa705a1ce665d571ee753bd81cbb67b92caa6d34722"),
89-
plot_size=uint8(42),
90+
plot_size=PlotSize.make_v1(42),
9091
pool_public_key=g1(
9192
"b6449c2c68df97c19e884427e42ee7350982d4020571ead08732615ff39bd216bfd630b6460784982bec98b49fea79d0"
9293
),
@@ -99,7 +100,7 @@ def b32(key: str) -> bytes32:
99100
ProofOfSpaceCase(
100101
id="Passing the plot filter with size 8",
101102
pos_challenge=b32("08b23cc2844dfb92d2eedaa705a1ce665d571ee753bd81cbb67b92caa6d34722"),
102-
plot_size=uint8(42),
103+
plot_size=PlotSize.make_v1(42),
103104
pool_public_key=g1(
104105
"b6449c2c68df97c19e884427e42ee7350982d4020571ead08732615ff39bd216bfd630b6460784982bec98b49fea79d0"
105106
),
@@ -111,23 +112,23 @@ def b32(key: str) -> bytes32:
111112
ProofOfSpaceCase(
112113
id="v2 plot size 0",
113114
pos_challenge=bytes32(b"1" * 32),
114-
plot_size=uint8(0x80),
115+
plot_size=PlotSize.make_v2(0),
115116
plot_public_key=G1Element(),
116117
pool_public_key=G1Element(),
117118
expected_error="Plot size is lower than the minimum",
118119
),
119120
ProofOfSpaceCase(
120121
id="v2 plot size 34",
121122
pos_challenge=bytes32(b"1" * 32),
122-
plot_size=uint8(0x80 | 34),
123+
plot_size=PlotSize.make_v2(34),
123124
plot_public_key=G1Element(),
124125
pool_public_key=G1Element(),
125126
expected_error="Plot size is higher than the maximum",
126127
),
127128
ProofOfSpaceCase(
128129
id="Not passing the plot filter v2",
129130
pos_challenge=b32("3d29ea79d19b3f7e99ebf764ae53697cbe143603909873946af6ab1ece606861"),
130-
plot_size=uint8(0x80 | 32),
131+
plot_size=PlotSize.make_v2(32),
131132
pool_public_key=g1(
132133
"b6449c2c68df97c19e884427e42ee7350982d4020571ead08732615ff39bd216bfd630b6460784982bec98b49fea79d0"
133134
),
@@ -138,7 +139,7 @@ def b32(key: str) -> bytes32:
138139
),
139140
)
140141
def test_verify_and_get_quality_string(caplog: pytest.LogCaptureFixture, case: ProofOfSpaceCase) -> None:
141-
pos = ProofOfSpace(
142+
pos = make_pos(
142143
challenge=case.pos_challenge,
143144
pool_public_key=case.pool_public_key,
144145
pool_contract_puzzle_hash=case.pool_contract_puzzle_hash,
@@ -160,7 +161,7 @@ def test_verify_and_get_quality_string(caplog: pytest.LogCaptureFixture, case: P
160161
@datacases(
161162
ProofOfSpaceCase(
162163
id="v2 plot are not implemented",
163-
plot_size=uint8(0x80 | 30),
164+
plot_size=PlotSize.make_v2(30),
164165
pos_challenge=b32("47deb938e145d25d7b3b3c85ca9e3972b76c01aeeb78a02fe5d3b040d282317e"),
165166
plot_public_key=g1(
166167
"afa3aaf09c03885154be49216ee7fb2e4581b9c4a4d7e9cc402e27280bf0cfdbdf1b9ba674e301fd1d1450234b3b1868"
@@ -172,7 +173,7 @@ def test_verify_and_get_quality_string(caplog: pytest.LogCaptureFixture, case: P
172173
),
173174
)
174175
def test_verify_and_get_quality_string_v2(caplog: pytest.LogCaptureFixture, case: ProofOfSpaceCase) -> None:
175-
pos = ProofOfSpace(
176+
pos = make_pos(
176177
challenge=case.pos_challenge,
177178
pool_public_key=case.pool_public_key,
178179
pool_contract_puzzle_hash=case.pool_contract_puzzle_hash,

chia/_tests/farmer_harvester/test_farmer.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from unittest.mock import ANY
1010

1111
import pytest
12-
from chia_rs import AugSchemeMPL, G1Element, G2Element, PrivateKey, ProofOfSpace
12+
from chia_rs import AugSchemeMPL, G1Element, G2Element, PlotSize, PrivateKey, ProofOfSpace
1313
from chia_rs.sized_bytes import bytes32
1414
from chia_rs.sized_ints import uint8, uint16, uint32, uint64
1515
from pytest_mock import MockerFixture
@@ -31,6 +31,7 @@
3131
from chia.simulator.block_tools import BlockTools
3232
from chia.types.blockchain_format.proof_of_space import (
3333
generate_plot_public_key,
34+
make_pos,
3435
verify_and_get_quality_string,
3536
)
3637
from chia.util.config import load_config, save_config
@@ -133,7 +134,7 @@ class NewProofOfSpaceCase:
133134
plot_identifier: str
134135
signage_point_index: uint8
135136
plot_id: bytes32
136-
plot_size: uint8
137+
plot_size: PlotSize
137138
plot_challenge: bytes32
138139
plot_public_key: G1Element
139140
pool_public_key: Optional[G1Element]
@@ -188,7 +189,7 @@ def create_verified_quality_case(
188189
plot_identifier="test",
189190
signage_point_index=uint8(1),
190191
plot_id=bytes32.fromhex("baaa6780c53d4b3739b8807b4ae79a76644ddf0d9e03dc7d0a6a0e613e764d9f"),
191-
plot_size=uint8(32),
192+
plot_size=PlotSize.make_v1(32),
192193
plot_challenge=bytes32.fromhex("7580e4c366dc2c94c37ce44943f9629a3cd6e027d7b24cd014adeaa578d4b0a2"),
193194
plot_public_key=G1Element.from_bytes(
194195
bytes.fromhex(
@@ -574,7 +575,7 @@ async def test_farmer_new_proof_of_space_for_pool_stats(
574575
peak_height=uint32(1),
575576
last_tx_height=uint32(0),
576577
)
577-
pos = ProofOfSpace(
578+
pos = make_pos(
578579
challenge=case.plot_challenge,
579580
pool_public_key=case.pool_public_key,
580581
pool_contract_puzzle_hash=case.pool_contract_puzzle_hash,
@@ -715,7 +716,7 @@ def create_valid_pos(farmer: Farmer) -> tuple[farmer_protocol.NewSignagePoint, P
715716
peak_height=uint32(1),
716717
last_tx_height=uint32(0),
717718
)
718-
pos = ProofOfSpace(
719+
pos = make_pos(
719720
challenge=case.plot_challenge,
720721
pool_public_key=case.pool_public_key,
721722
pool_contract_puzzle_hash=case.pool_contract_puzzle_hash,

chia/_tests/plot_sync/test_plot_sync.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,8 @@ async def plot_sync_callback(self, peer_id: bytes32, delta: Optional[Delta]) ->
195195
plot = harvester.plot_manager.plots.get(Path(path), None)
196196
assert plot is not None
197197
assert plot.prover.get_filename() == delta.valid.additions[path].filename
198-
assert plot.prover.get_size() == delta.valid.additions[path].size
198+
# TODO: todo_v2_plots support v2 plots
199+
assert plot.prover.get_size().size_v1 == delta.valid.additions[path].size
199200
assert plot.prover.get_id() == delta.valid.additions[path].plot_id
200201
assert plot.prover.get_compression_level() == delta.valid.additions[path].compression_level
201202
assert plot.pool_public_key == delta.valid.additions[path].pool_public_key
@@ -256,7 +257,8 @@ async def run_sync_test(self) -> None:
256257
for path, plot_info in plot_manager.plots.items():
257258
assert str(path) in receiver.plots()
258259
assert plot_info.prover.get_filename() == receiver.plots()[str(path)].filename
259-
assert plot_info.prover.get_size() == receiver.plots()[str(path)].size
260+
# TODO: todo_v2_plots support v2 plots
261+
assert plot_info.prover.get_size().size_v1 == receiver.plots()[str(path)].size
260262
assert plot_info.prover.get_id() == receiver.plots()[str(path)].plot_id
261263
assert plot_info.prover.get_compression_level() == receiver.plots()[str(path)].compression_level
262264
assert plot_info.pool_public_key == receiver.plots()[str(path)].pool_public_key

chia/_tests/plot_sync/test_receiver.py

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from typing import Any, Callable, Union
88

99
import pytest
10-
from chia_rs import G1Element
10+
from chia_rs import G1Element, PlotSize
1111
from chia_rs.sized_bytes import bytes32
1212
from chia_rs.sized_ints import uint8, uint32, uint64
1313

@@ -185,8 +185,12 @@ def plot_sync_setup(seeded_random: random.Random) -> tuple[Receiver, list[SyncSt
185185
# Manually add the plots we want to remove in tests
186186
receiver._plots = {plot_info.filename: plot_info for plot_info in plot_info_list[0:10]}
187187
receiver._total_plot_size = sum(plot.file_size for plot in receiver.plots().values())
188+
# TODO: todo_v2_plots support v2 plots
188189
receiver._total_effective_plot_size = int(
189-
sum(UI_ACTUAL_SPACE_CONSTANT_FACTOR * int(_expected_plot_size(plot.size)) for plot in receiver.plots().values())
190+
sum(
191+
UI_ACTUAL_SPACE_CONSTANT_FACTOR * int(_expected_plot_size(PlotSize.make_v1(plot.size)))
192+
for plot in receiver.plots().values()
193+
)
190194
)
191195
sync_steps: list[SyncStepData] = [
192196
SyncStepData(
@@ -266,7 +270,11 @@ async def test_to_dict(counts_only: bool, seeded_random: random.Random) -> None:
266270
assert get_list_or_len(plot_sync_dict_1["duplicates"], not counts_only) == 0
267271
assert plot_sync_dict_1["total_plot_size"] == sum(plot.file_size for plot in receiver.plots().values())
268272
assert plot_sync_dict_1["total_effective_plot_size"] == int(
269-
sum(UI_ACTUAL_SPACE_CONSTANT_FACTOR * int(_expected_plot_size(plot.size)) for plot in receiver.plots().values())
273+
# TODO: todo_v2_plots support v2 plots
274+
sum(
275+
UI_ACTUAL_SPACE_CONSTANT_FACTOR * int(_expected_plot_size(PlotSize.make_v1(plot.size)))
276+
for plot in receiver.plots().values()
277+
)
270278
)
271279
assert plot_sync_dict_1["syncing"] is None
272280
assert plot_sync_dict_1["last_sync_time"] is None
@@ -312,8 +320,12 @@ async def test_to_dict(counts_only: bool, seeded_random: random.Random) -> None:
312320
assert get_list_or_len(sync_steps[State.duplicates].args[0], counts_only) == plot_sync_dict_3["duplicates"]
313321

314322
assert plot_sync_dict_3["total_plot_size"] == sum(plot.file_size for plot in receiver.plots().values())
323+
# TODO: todo_v2_plots support v2 plots
315324
assert plot_sync_dict_3["total_effective_plot_size"] == int(
316-
sum(UI_ACTUAL_SPACE_CONSTANT_FACTOR * int(_expected_plot_size(plot.size)) for plot in receiver.plots().values())
325+
sum(
326+
UI_ACTUAL_SPACE_CONSTANT_FACTOR * int(_expected_plot_size(PlotSize.make_v1(plot.size)))
327+
for plot in receiver.plots().values()
328+
)
317329
)
318330
assert plot_sync_dict_3["last_sync_time"] > 0
319331
assert plot_sync_dict_3["syncing"] is None

chia/_tests/plotting/test_plot_manager.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -508,7 +508,8 @@ async def test_plot_info_caching(environment, bt):
508508
assert plot_manager.plots[path].prover.get_filename() == plot_info.prover.get_filename()
509509
assert plot_manager.plots[path].prover.get_id() == plot_info.prover.get_id()
510510
assert plot_manager.plots[path].prover.get_memo() == plot_info.prover.get_memo()
511-
assert plot_manager.plots[path].prover.get_size() == plot_info.prover.get_size()
511+
assert plot_manager.plots[path].prover.get_size().size_v1 == plot_info.prover.get_size().size_v1
512+
assert plot_manager.plots[path].prover.get_size().size_v2 == plot_info.prover.get_size().size_v2
512513
assert plot_manager.plots[path].prover.get_compression_level() == plot_info.prover.get_compression_level()
513514
assert plot_manager.plots[path].pool_public_key == plot_info.pool_public_key
514515
assert plot_manager.plots[path].pool_contract_puzzle_hash == plot_info.pool_contract_puzzle_hash

chia/_tests/util/test_full_block_utils.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -67,14 +67,15 @@ def vdf_proof() -> VDFProof:
6767
def get_proof_of_space() -> Generator[ProofOfSpace, None, None]:
6868
for pool_pk in [g1(), None]:
6969
for plot_hash in [hsh(), None]:
70-
yield ProofOfSpace(
71-
hsh(), # challenge
72-
pool_pk,
73-
plot_hash,
74-
g1(), # plot_public_key
75-
uint8(32),
76-
random.randbytes(8 * 32),
77-
)
70+
for pos_version in [0, 0x80]:
71+
yield ProofOfSpace(
72+
hsh(), # challenge
73+
pool_pk,
74+
plot_hash,
75+
g1(), # plot_public_key
76+
uint8(pos_version | 32), # this is version and k-size
77+
random.randbytes(8 * 32),
78+
)
7879

7980

8081
def get_reward_chain_block(height: uint32) -> Generator[RewardChainBlock, None, None]:

chia/consensus/pos_quality.py

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,21 @@
11
from __future__ import annotations
22

3+
from chia_rs import PlotSize
34
from chia_rs.sized_ints import uint64
45

56
# The actual space in bytes of a plot, is _expected_plot_size(k) * UI_ACTUAL_SPACE_CONSTANT_FACTO
67
# This is not used in consensus, only for display purposes
78
UI_ACTUAL_SPACE_CONSTANT_FACTOR = 0.78
89

10+
# these values are from CHIP-48
11+
v2_plot_sizes: dict[int, uint64] = {
12+
28: uint64(1717986918),
13+
30: uint64(4509715660),
14+
32: uint64(11381663334),
15+
}
916

10-
def _expected_plot_size(k: int) -> uint64:
17+
18+
def _expected_plot_size(size: PlotSize) -> uint64:
1119
"""
1220
Given the plot size parameter k (which is between 32 and 59), computes the
1321
expected size of the plot in bytes (times a constant factor). This is based on efficient encoding
@@ -16,4 +24,15 @@ def _expected_plot_size(k: int) -> uint64:
1624
is necessary to store the entries in the plot.
1725
"""
1826

19-
return uint64(((2 * k) + 1) * (2 ** (k - 1)))
27+
k: int
28+
if size.size_v1 is not None:
29+
k = size.size_v1
30+
return uint64(((2 * k) + 1) * (2 ** (k - 1)))
31+
else:
32+
assert size.size_v2 is not None
33+
k = size.size_v2
34+
if k in v2_plot_sizes:
35+
return v2_plot_sizes[k]
36+
else:
37+
# TODO: todo_v2_plots support test plots with lower k-values
38+
return uint64(0)

0 commit comments

Comments
 (0)