@@ -2,7 +2,7 @@ use fil_actor_market::{DealMetaArray, SectorDeals, State as MarketState};
2
2
use fil_actor_miner:: {
3
3
max_prove_commit_duration, power_for_sector, ExpirationExtension , ExpirationExtension2 ,
4
4
ExtendSectorExpiration2Params , ExtendSectorExpirationParams , Method as MinerMethod , PowerPair ,
5
- ProveReplicaUpdatesParams2 , ReplicaUpdate2 , SectorClaim , State as MinerState ,
5
+ ProveReplicaUpdatesParams2 , ReplicaUpdate2 , SectorClaim , Sectors , State as MinerState ,
6
6
} ;
7
7
use fil_actor_verifreg:: Method as VerifregMethod ;
8
8
use fil_actors_runtime:: runtime:: Policy ;
@@ -18,15 +18,16 @@ use fvm_shared::econ::TokenAmount;
18
18
use fvm_shared:: piece:: PaddedPieceSize ;
19
19
use fvm_shared:: sector:: { RegisteredSealProof , SectorNumber , StoragePower } ;
20
20
use vm_api:: trace:: ExpectInvocation ;
21
- use vm_api:: util:: { apply_ok, get_state, DynBlockstore } ;
21
+ use vm_api:: util:: { apply_ok, get_state, mutate_state , DynBlockstore } ;
22
22
use vm_api:: VM ;
23
23
24
24
use crate :: expects:: Expect ;
25
25
use crate :: util:: {
26
- advance_by_deadline_to_epoch, advance_by_deadline_to_index, advance_to_proving_deadline,
27
- bf_all, create_accounts, create_miner, cron_tick, market_add_balance, market_publish_deal,
28
- miner_precommit_sector, miner_prove_sector, sector_deadline, submit_windowed_post,
29
- verifreg_add_client, verifreg_add_verifier,
26
+ advance_by_deadline_to_epoch, advance_by_deadline_to_epoch_while_proving,
27
+ advance_by_deadline_to_index, advance_to_proving_deadline, bf_all, create_accounts,
28
+ create_miner, cron_tick, expect_invariants, invariant_failure_patterns, market_add_balance,
29
+ market_publish_deal, miner_precommit_sector, miner_prove_sector, sector_deadline,
30
+ submit_windowed_post, verifreg_add_client, verifreg_add_verifier,
30
31
} ;
31
32
32
33
#[ allow( clippy:: too_many_arguments) ]
@@ -103,6 +104,220 @@ pub fn extend(
103
104
. matches ( v. take_invocations ( ) . last ( ) . unwrap ( ) ) ;
104
105
}
105
106
107
+ pub fn extend_legacy_sector_with_deals_test ( v : & dyn VM , do_extend2 : bool ) {
108
+ let addrs = create_accounts ( v, 3 , & TokenAmount :: from_whole ( 10_000 ) ) ;
109
+ let seal_proof = RegisteredSealProof :: StackedDRG32GiBV1P1 ;
110
+ let ( owner, worker, verifier, verified_client) = ( addrs[ 0 ] , addrs[ 0 ] , addrs[ 1 ] , addrs[ 2 ] ) ;
111
+ let sector_number: SectorNumber = 100 ;
112
+ let policy = Policy :: default ( ) ;
113
+
114
+ // create miner
115
+ let miner_id = create_miner (
116
+ v,
117
+ & owner,
118
+ & worker,
119
+ seal_proof. registered_window_post_proof ( ) . unwrap ( ) ,
120
+ & TokenAmount :: from_whole ( 1_000 ) ,
121
+ )
122
+ . 0 ;
123
+ v. set_epoch ( 200 ) ;
124
+
125
+ //
126
+ // publish verified deals
127
+ //
128
+
129
+ // register verifier then verified client
130
+ let datacap = StoragePower :: from ( 32_u128 << 40 ) ;
131
+ verifreg_add_verifier ( v, & verifier, datacap. clone ( ) ) ;
132
+ verifreg_add_client ( v, & verifier, & verified_client, datacap) ;
133
+
134
+ // add market collateral for clients and miner
135
+ market_add_balance ( v, & verified_client, & verified_client, & TokenAmount :: from_whole ( 3 ) ) ;
136
+ market_add_balance ( v, & worker, & miner_id, & TokenAmount :: from_whole ( 64 ) ) ;
137
+
138
+ // create 1 verified deal for total sector capacity for 6 months
139
+ let deal_start = v. epoch ( ) + max_prove_commit_duration ( & Policy :: default ( ) , seal_proof) . unwrap ( ) ;
140
+ let deals = market_publish_deal (
141
+ v,
142
+ & worker,
143
+ & verified_client,
144
+ & miner_id,
145
+ "deal1" . to_string ( ) ,
146
+ PaddedPieceSize ( 32u64 << 30 ) ,
147
+ true ,
148
+ deal_start,
149
+ 180 * EPOCHS_IN_DAY ,
150
+ )
151
+ . ids ;
152
+
153
+ //
154
+ // Precommit, prove and PoSt empty sector (more fully tested in TestCommitPoStFlow)
155
+ //
156
+
157
+ miner_precommit_sector (
158
+ v,
159
+ & worker,
160
+ & miner_id,
161
+ seal_proof,
162
+ sector_number,
163
+ deals,
164
+ deal_start + 180 * EPOCHS_IN_DAY ,
165
+ ) ;
166
+
167
+ // advance time to max seal duration and prove the sector
168
+ advance_by_deadline_to_epoch ( v, & miner_id, deal_start) ;
169
+ miner_prove_sector ( v, & worker, & miner_id, sector_number) ;
170
+ // trigger cron to validate the prove commit
171
+ cron_tick ( v) ;
172
+
173
+ // inspect sector info
174
+
175
+ let miner_state: MinerState = get_state ( v, & miner_id) . unwrap ( ) ;
176
+ let mut sector_info = miner_state
177
+ . get_sector ( & DynBlockstore :: wrap ( v. blockstore ( ) ) , sector_number)
178
+ . unwrap ( )
179
+ . unwrap ( ) ;
180
+ assert_eq ! ( 180 * EPOCHS_IN_DAY , sector_info. expiration - sector_info. activation) ;
181
+ assert_eq ! ( StoragePower :: zero( ) , sector_info. deal_weight) ; // 0 space time
182
+ assert_eq ! (
183
+ DealWeight :: from( 180 * EPOCHS_IN_DAY * ( 32i64 << 30 ) ) ,
184
+ sector_info. verified_deal_weight
185
+ ) ; // (180 days *2880 epochs per day) * 32 GiB
186
+
187
+ // Note: we don't need to explicitly set verified weight using the legacy method
188
+ // because legacy and simple qa power deal weight calculations line up for fully packed sectors
189
+ // We do need to set simple_qa_power to false
190
+ sector_info. simple_qa_power = false ;
191
+
192
+ // Manually craft state to match legacy sectors
193
+ mutate_state ( v, & miner_id, |st : & mut MinerState | {
194
+ let store = & DynBlockstore :: wrap ( v. blockstore ( ) ) ;
195
+ let mut sectors = Sectors :: load ( store, & st. sectors ) . unwrap ( ) ;
196
+ sectors. store ( vec ! [ sector_info. clone( ) ] ) . unwrap ( ) ;
197
+ st. sectors = sectors. amt . flush ( ) . unwrap ( ) ;
198
+ } ) ;
199
+
200
+ let initial_verified_deal_weight = sector_info. verified_deal_weight ;
201
+ let initial_deal_weight = sector_info. deal_weight ;
202
+
203
+ // advance to proving period and submit post
204
+ let ( deadline_info, partition_index) = advance_to_proving_deadline ( v, & miner_id, sector_number) ;
205
+ let expected_power_delta = PowerPair {
206
+ raw : StoragePower :: from ( 32u64 << 30 ) ,
207
+ qa : StoragePower :: from ( 10 * ( 32u64 << 30 ) ) ,
208
+ } ;
209
+ submit_windowed_post (
210
+ v,
211
+ & worker,
212
+ & miner_id,
213
+ deadline_info,
214
+ partition_index,
215
+ Some ( expected_power_delta) ,
216
+ ) ;
217
+
218
+ // move forward one deadline so advanceWhileProving doesn't fail double submitting posts
219
+ advance_by_deadline_to_index (
220
+ v,
221
+ & miner_id,
222
+ deadline_info. index + 1 % policy. wpost_period_deadlines ,
223
+ ) ;
224
+
225
+ // Advance halfway through life and extend another 6 months. We need to spread the remaining 90
226
+ // days of 10x power over 90 + 180 days
227
+ // subtract half the remaining deal weight:
228
+ // - verified deal weight /= 2
229
+ //
230
+ // normalize 90 days of 10x power plus 180 days of 1x power over 90+180 days:
231
+ // - multiplier = ((10 * 90) + (1 * 180)) / (90 + 180)
232
+ // - multiplier = 4
233
+ //
234
+ // delta from the previous 10x power multiplier:
235
+ // - power delta = (10-4)*32GiB = 6*32GiB
236
+ advance_by_deadline_to_epoch_while_proving (
237
+ v,
238
+ & miner_id,
239
+ & worker,
240
+ sector_number,
241
+ deal_start + 90 * EPOCHS_IN_DAY ,
242
+ ) ;
243
+
244
+ let new_expiration = deal_start + 2 * 180 * EPOCHS_IN_DAY ;
245
+ let expected_power_delta =
246
+ PowerPair { raw : StoragePower :: zero ( ) , qa : StoragePower :: from ( -6 * ( 32i64 << 30 ) ) } ;
247
+ extend (
248
+ v,
249
+ worker,
250
+ miner_id,
251
+ deadline_info. index ,
252
+ partition_index,
253
+ sector_number,
254
+ new_expiration,
255
+ expected_power_delta,
256
+ do_extend2,
257
+ ) ;
258
+
259
+ let miner_state: MinerState = get_state ( v, & miner_id) . unwrap ( ) ;
260
+ sector_info = miner_state
261
+ . get_sector ( & DynBlockstore :: wrap ( v. blockstore ( ) ) , sector_number)
262
+ . unwrap ( )
263
+ . unwrap ( ) ;
264
+ assert_eq ! ( 180 * 2 * EPOCHS_IN_DAY , sector_info. expiration - sector_info. activation) ;
265
+ assert_eq ! ( initial_deal_weight, sector_info. deal_weight) ; // 0 space time, unchanged
266
+ assert_eq ! ( & initial_verified_deal_weight / 2 , sector_info. verified_deal_weight) ;
267
+
268
+ // advance to 6 months (original expiration) and extend another 6 months
269
+ //
270
+ // We're 1/3rd of the way through the last extension, so keep 2/3 of the power.
271
+ // - verified deal weight *= 2/3
272
+ //
273
+ // normalize 180 days of 4x power plus 180 days of 1x power over 180+180 days:
274
+ // - multiplier = ((4 * 180) + (1 * 180)) / (90 + 180)
275
+ // - multiplier = 2.5
276
+ //
277
+ // delta from the previous 4x power multiplier:
278
+ // - power delta = (4-2.5)*32GiB = 1.5*32GiB
279
+
280
+ advance_by_deadline_to_epoch_while_proving (
281
+ v,
282
+ & miner_id,
283
+ & worker,
284
+ sector_number,
285
+ deal_start + 180 * EPOCHS_IN_DAY ,
286
+ ) ;
287
+
288
+ let new_expiration = deal_start + 3 * 180 * EPOCHS_IN_DAY ;
289
+ let expected_power_delta =
290
+ PowerPair { raw : StoragePower :: zero ( ) , qa : StoragePower :: from ( -15 * ( 32i64 << 30 ) / 10 ) } ;
291
+ extend (
292
+ v,
293
+ worker,
294
+ miner_id,
295
+ deadline_info. index ,
296
+ partition_index,
297
+ sector_number,
298
+ new_expiration,
299
+ expected_power_delta,
300
+ do_extend2,
301
+ ) ;
302
+
303
+ let miner_state: MinerState = get_state ( v, & miner_id) . unwrap ( ) ;
304
+ let sector_info = miner_state
305
+ . get_sector ( & DynBlockstore :: wrap ( v. blockstore ( ) ) , sector_number)
306
+ . unwrap ( )
307
+ . unwrap ( ) ;
308
+ assert_eq ! ( 180 * 3 * EPOCHS_IN_DAY , sector_info. expiration - sector_info. activation) ;
309
+ // 0 space time, unchanged
310
+ assert_eq ! ( initial_deal_weight, sector_info. deal_weight) ;
311
+ // 1/2 * 2/3 -> 1/3
312
+ assert_eq ! ( initial_verified_deal_weight / 3 , sector_info. verified_deal_weight) ;
313
+
314
+ expect_invariants (
315
+ v,
316
+ & Policy :: default ( ) ,
317
+ & [ invariant_failure_patterns:: REWARD_STATE_EPOCH_MISMATCH . to_owned ( ) ] ,
318
+ ) ;
319
+ }
320
+
106
321
pub fn commit_sector_with_max_duration_deal_test ( v : & dyn VM ) {
107
322
let addrs = create_accounts ( v, 3 , & TokenAmount :: from_whole ( 10_000 ) ) ;
108
323
let seal_proof = RegisteredSealProof :: StackedDRG32GiBV1P1 ;
0 commit comments