4
4
from unittest .mock import MagicMock , patch
5
5
6
6
import pytest
7
- from chia_rs import ProofOfSpace
7
+ from chia_rs import ConsensusConstants , FullBlock , ProofOfSpace
8
8
from chia_rs .sized_bytes import bytes32
9
9
from chia_rs .sized_ints import uint64
10
10
14
14
from chia .protocols import harvester_protocol
15
15
from chia .protocols .harvester_protocol import PoolDifficulty
16
16
from chia .server .ws_connection import WSChiaConnection
17
- from chia .simulator .block_tools import BlockTools
18
17
19
18
20
- def signage_point_from_block (bt : BlockTools ) -> harvester_protocol .NewSignagePointHarvester :
21
- """Create a real NewSignagePointHarvester from actual blockchain blocks."""
22
- # generate real blocks using BlockTools
23
- blocks = bt .get_consecutive_blocks (
24
- num_blocks = 3 ,
25
- guarantee_transaction_block = True ,
26
- farmer_reward_puzzle_hash = bt .farmer_ph ,
27
- )
28
- block = blocks [- 1 ] # always use the last block
19
+ def signage_point_from_block (
20
+ block : FullBlock , constants : ConsensusConstants
21
+ ) -> harvester_protocol .NewSignagePointHarvester :
22
+ """Create a real NewSignagePointHarvester from a blockchain block."""
29
23
# extract real signage point data from the block
30
24
sp_index = block .reward_chain_block .signage_point_index
31
25
challenge_hash = block .reward_chain_block .pos_ss_cc_challenge_hash
@@ -37,8 +31,8 @@ def signage_point_from_block(bt: BlockTools) -> harvester_protocol.NewSignagePoi
37
31
38
32
return harvester_protocol .NewSignagePointHarvester (
39
33
challenge_hash = challenge_hash ,
40
- difficulty = uint64 (bt . constants .DIFFICULTY_STARTING ),
41
- sub_slot_iters = uint64 (bt . constants .SUB_SLOT_ITERS_STARTING ),
34
+ difficulty = uint64 (constants .DIFFICULTY_STARTING ),
35
+ sub_slot_iters = uint64 (constants .SUB_SLOT_ITERS_STARTING ),
42
36
signage_point_index = sp_index ,
43
37
sp_hash = sp_hash ,
44
38
pool_difficulties = [],
@@ -63,21 +57,25 @@ def create_plot_info() -> PlotInfo:
63
57
64
58
65
59
@pytest .mark .anyio
66
- async def test_new_signage_point_harvester (harvester_farmer_environment : HarvesterFarmerEnvironment ) -> None :
60
+ async def test_new_signage_point_harvester (
61
+ harvester_farmer_environment : HarvesterFarmerEnvironment ,
62
+ default_400_blocks : list [FullBlock ],
63
+ blockchain_constants : ConsensusConstants ,
64
+ ) -> None :
67
65
"""Test successful signage point processing with real blockchain data."""
68
- _ , _ , harvester_service , _ , bt = harvester_farmer_environment
66
+ _ , _ , harvester_service , _ , _ = harvester_farmer_environment
69
67
harvester_api = harvester_service ._server .api
70
68
assert isinstance (harvester_api , HarvesterAPI )
71
69
# use real signage point data from actual block
72
- new_challenge = signage_point_from_block (bt )
70
+ block = default_400_blocks [2 ] # use a transaction block
71
+ new_challenge = signage_point_from_block (block , blockchain_constants )
73
72
# harvester doesn't accept incoming connections, so use mock peer like other tests
74
73
mock_peer = MagicMock (spec = WSChiaConnection )
75
74
# create realistic plot info for testing
76
75
mock_plot_info = create_plot_info ()
77
- plot_path = Path ("/fake/plot.plot" )
78
76
79
77
with patch .object (harvester_api .harvester .plot_manager , "public_keys_available" , return_value = True ):
80
- with patch .object (harvester_api .harvester .plot_manager , "plots" , {plot_path : mock_plot_info }):
78
+ with patch .object (harvester_api .harvester .plot_manager , "plots" , {"tmp_path" : mock_plot_info }):
81
79
# let passes_plot_filter, calculate_pos_challenge, and calculate_sp_interval_iters use real implementations
82
80
with patch ("chia.harvester.harvester_api.calculate_iterations_quality" , return_value = uint64 (1000 )):
83
81
with patch .object (mock_plot_info .prover , "get_full_proof" ) as mock_get_proof :
@@ -89,9 +87,12 @@ async def test_new_signage_point_harvester(harvester_farmer_environment: Harvest
89
87
@pytest .mark .anyio
90
88
async def test_new_signage_point_harvester_pool_difficulty (
91
89
harvester_farmer_environment : HarvesterFarmerEnvironment ,
90
+ default_400_blocks : list [FullBlock ],
91
+ tmp_path : Path ,
92
+ blockchain_constants : ConsensusConstants ,
92
93
) -> None :
93
94
"""Test pool difficulty overrides with real blockchain signage points."""
94
- _ , _ , harvester_service , _ , bt = harvester_farmer_environment
95
+ _ , _ , harvester_service , _ , _ = harvester_farmer_environment
95
96
harvester_api = harvester_service ._server .api
96
97
assert isinstance (harvester_api , HarvesterAPI )
97
98
@@ -102,15 +103,15 @@ async def test_new_signage_point_harvester_pool_difficulty(
102
103
# create realistic plot info for testing
103
104
mock_plot_info = create_plot_info ()
104
105
mock_plot_info .pool_contract_puzzle_hash = pool_puzzle_hash
105
- plot_path = Path ("/fake/pool_plot.plot" )
106
106
pool_difficulty = PoolDifficulty (
107
107
pool_contract_puzzle_hash = pool_puzzle_hash ,
108
108
difficulty = uint64 (500 ), # lower than main difficulty
109
109
sub_slot_iters = uint64 (67108864 ), # different from main
110
110
)
111
111
112
112
# create signage point from real block with pool difficulty
113
- new_challenge = signage_point_from_block (bt )
113
+ block = default_400_blocks [2 ] # use a transaction block
114
+ new_challenge = signage_point_from_block (block , blockchain_constants )
114
115
new_challenge = harvester_protocol .NewSignagePointHarvester (
115
116
challenge_hash = new_challenge .challenge_hash ,
116
117
difficulty = new_challenge .difficulty ,
@@ -123,7 +124,7 @@ async def test_new_signage_point_harvester_pool_difficulty(
123
124
)
124
125
125
126
with patch .object (harvester_api .harvester .plot_manager , "public_keys_available" , return_value = True ):
126
- with patch .object (harvester_api .harvester .plot_manager , "plots" , {plot_path : mock_plot_info }):
127
+ with patch .object (harvester_api .harvester .plot_manager , "plots" , {tmp_path : mock_plot_info }):
127
128
# mock passes_plot_filter to return True so we can test pool difficulty logic
128
129
with patch ("chia.harvester.harvester_api.passes_plot_filter" , return_value = True ):
129
130
with patch ("chia.harvester.harvester_api.calculate_iterations_quality" ) as mock_calc_iter :
@@ -141,23 +142,26 @@ async def test_new_signage_point_harvester_pool_difficulty(
141
142
@pytest .mark .anyio
142
143
async def test_new_signage_point_harvester_prover_error (
143
144
harvester_farmer_environment : HarvesterFarmerEnvironment ,
145
+ default_400_blocks : list [FullBlock ],
146
+ tmp_path : Path ,
147
+ blockchain_constants : ConsensusConstants ,
144
148
) -> None :
145
149
"""Test error handling when prover fails using real blockchain data."""
146
- _ , _ , harvester_service , _ , bt = harvester_farmer_environment
150
+ _ , _ , harvester_service , _ , _ = harvester_farmer_environment
147
151
harvester_api = harvester_service ._server .api
148
152
assert isinstance (harvester_api , HarvesterAPI )
149
153
150
154
# create signage point from real block
151
- new_challenge = signage_point_from_block (bt )
155
+ block = default_400_blocks [2 ] # use a transaction block
156
+ new_challenge = signage_point_from_block (block , blockchain_constants )
152
157
153
158
mock_peer = MagicMock (spec = WSChiaConnection )
154
159
155
160
# create realistic plot info for testing
156
161
mock_plot_info = create_plot_info ()
157
- plot_path = Path ("/fake/plot.plot" )
158
162
159
163
with patch .object (harvester_api .harvester .plot_manager , "public_keys_available" , return_value = True ):
160
- with patch .object (harvester_api .harvester .plot_manager , "plots" , {plot_path : mock_plot_info }):
164
+ with patch .object (harvester_api .harvester .plot_manager , "plots" , {tmp_path : mock_plot_info }):
161
165
# let passes_plot_filter and calculate_pos_challenge use real implementations
162
166
# make the prover fail during quality check
163
167
with patch .object (
0 commit comments