Skip to content

Commit 16e7c9b

Browse files
committed
address review comments
1 parent 446bfa8 commit 16e7c9b

File tree

1 file changed

+41
-16
lines changed

1 file changed

+41
-16
lines changed

chia/_tests/core/consensus/test_pot_iterations.py

Lines changed: 41 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from __future__ import annotations
22

3+
import pytest
34
from chia_rs import PlotSize
45
from chia_rs.sized_ints import uint8, uint16, uint32, uint64, uint128
56
from pytest import raises
@@ -83,7 +84,17 @@ def test_calculate_ip_iters(self):
8384
assert ip_iters == (sp_iters + test_constants.NUM_SP_INTERVALS_EXTRA * sp_interval_iters + required_iters) % ssi
8485
assert sp_iters > ip_iters
8586

86-
def test_win_percentage(self):
87+
@pytest.mark.parametrize(
88+
"height",
89+
[
90+
uint32(0),
91+
test_constants.HARD_FORK2_HEIGHT - 1,
92+
test_constants.HARD_FORK2_HEIGHT,
93+
test_constants.HARD_FORK2_HEIGHT + test_constants.PLOT_V1_PHASE_OUT,
94+
test_constants.HARD_FORK2_HEIGHT + test_constants.PLOT_V1_PHASE_OUT + 1,
95+
],
96+
)
97+
def test_win_percentage(self, height: uint32):
8798
"""
8899
Tests that the percentage of blocks won is proportional to the space of each farmer,
89100
with the assumption that all farmers have access to the same VDF speed.
@@ -94,61 +105,75 @@ def test_win_percentage(self):
94105
PlotSize.make_v1(34): 100,
95106
PlotSize.make_v1(35): 100,
96107
PlotSize.make_v1(36): 100,
97-
PlotSize.make_v2(28): 100,
98-
PlotSize.make_v2(30): 100,
99-
PlotSize.make_v2(32): 100,
108+
PlotSize.make_v2(28): 200,
109+
PlotSize.make_v2(30): 200,
110+
PlotSize.make_v2(32): 200,
100111
}
101112
farmer_space = {k: _expected_plot_size(k) * count for k, count in farmer_ks.items()}
102-
total_space = sum(farmer_space.values())
103-
percentage_space = {k: float(sp / total_space) for k, sp in farmer_space.items()}
104113
wins = {k: 0 for k in farmer_ks.keys()}
114+
115+
constants = test_constants.replace(DIFFICULTY_CONSTANT_FACTOR=uint128(2**25))
105116
total_slots = 50
106117
num_sps = 16
107-
sp_interval_iters = uint64(100000000 // 32)
118+
sub_slot_iters = uint64(100000000)
119+
sp_interval_iters = calculate_sp_interval_iters(constants, sub_slot_iters)
108120
difficulty = uint64(500000000000)
109-
constants = test_constants.replace(DIFFICULTY_CONSTANT_FACTOR=uint128(2**25))
110121
for slot_index in range(total_slots):
111122
total_wins_in_slot = 0
112123
for sp_index in range(num_sps):
113124
sp_hash = std_hash(slot_index.to_bytes(4, "big") + sp_index.to_bytes(4, "big"))
114125
for k, count in farmer_ks.items():
115126
for farmer_index in range(count):
116127
plot_k_val = k.size_v1 if k.size_v2 is None else k.size_v2
128+
assert plot_k_val is not None
117129
quality = std_hash(
118130
slot_index.to_bytes(4, "big") + plot_k_val.to_bytes(1, "big") + bytes(farmer_index)
119131
)
120132
required_iters = calculate_iterations_quality(
121-
constants, quality, k, difficulty, sp_hash, uint64(100000000), uint32(0)
133+
constants, quality, k, difficulty, sp_hash, sub_slot_iters, height
122134
)
123135
if required_iters < sp_interval_iters:
124136
wins[k] += 1
125137
total_wins_in_slot += 1
126138

139+
if height < test_constants.HARD_FORK2_HEIGHT + test_constants.PLOT_V1_PHASE_OUT:
140+
total_space = sum(farmer_space.values())
141+
percentage_space = {k: float(sp / total_space) for k, sp in farmer_space.items()}
142+
else:
143+
# after the phase-out, v1 plots don't count
144+
# all wins are by v2 plots
145+
total_space = sum(0 if k.size_v2 is None else sp for k, sp in farmer_space.items())
146+
percentage_space = {
147+
k: 0.0 if k.size_v2 is None else float(sp / total_space) for k, sp in farmer_space.items()
148+
}
149+
127150
win_percentage = {k: wins[k] / sum(wins.values()) for k in farmer_ks.keys()}
128151
for k in farmer_ks.keys():
129152
# Win rate is proportional to percentage of space
130153
assert abs(win_percentage[k] - percentage_space[k]) < 0.01
131154

132-
def test_calculate_phase_out(self):
155+
@pytest.mark.parametrize("sp_interval", [uint64(6250000000), uint64(1), uint64(2), uint64(10), uint64(10000000000)])
156+
def test_calculate_phase_out(self, sp_interval: uint64):
133157
constants = test_constants
134-
sub_slot_iters = uint64(100000000000)
135-
sp_interval = calculate_sp_interval_iters(constants, sub_slot_iters)
158+
sub_slot_iters = uint64(sp_interval * constants.NUM_SPS_SUB_SLOT)
136159
# Before or at HARD_FORK2_HEIGHT, should return 0
137-
assert calculate_phase_out(constants, sub_slot_iters, constants.HARD_FORK2_HEIGHT - 1) == 0
160+
assert calculate_phase_out(constants, sub_slot_iters, uint32(constants.HARD_FORK2_HEIGHT - 1)) == 0
138161
assert calculate_phase_out(constants, sub_slot_iters, constants.HARD_FORK2_HEIGHT) == 0
139162
# after HARD_FORK2_HEIGHT, should return value = delta/phase_out_period * sp_interval
140163
assert (
141-
calculate_phase_out(constants, sub_slot_iters, constants.HARD_FORK2_HEIGHT + 1)
164+
calculate_phase_out(constants, sub_slot_iters, uint32(constants.HARD_FORK2_HEIGHT + 1))
142165
== sp_interval // constants.PLOT_V1_PHASE_OUT
143166
)
144167
assert (
145168
calculate_phase_out(
146-
constants, sub_slot_iters, constants.HARD_FORK2_HEIGHT + constants.PLOT_V1_PHASE_OUT // 2
169+
constants, sub_slot_iters, uint32(constants.HARD_FORK2_HEIGHT + constants.PLOT_V1_PHASE_OUT // 2)
147170
)
148171
== sp_interval // 2
149172
)
150173
assert (
151-
calculate_phase_out(constants, sub_slot_iters, constants.HARD_FORK2_HEIGHT + constants.PLOT_V1_PHASE_OUT)
174+
calculate_phase_out(
175+
constants, sub_slot_iters, uint32(constants.HARD_FORK2_HEIGHT + constants.PLOT_V1_PHASE_OUT)
176+
)
152177
== sp_interval
153178
)
154179

0 commit comments

Comments
 (0)