Skip to content

Commit

Permalink
FIP-0052 - extend max sector and deal duration to 3.5 years (#1272)
Browse files Browse the repository at this point in the history
* FIP-0052 sector/deal duration to be 3.5 year maxx

* Cleanup

---------

Co-authored-by: zenground0 <ZenGround0@users.noreply.github.com>
Co-authored-by: ZenGround0 <5515260+ZenGround0@users.noreply.github.com>
  • Loading branch information
3 people authored Apr 7, 2023
1 parent 49db254 commit f28bfd0
Show file tree
Hide file tree
Showing 4 changed files with 269 additions and 26 deletions.
2 changes: 1 addition & 1 deletion actors/market/src/policy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ pub mod detail {

/// Bounds (inclusive) on deal duration.
pub(super) fn deal_duration_bounds(_size: PaddedPieceSize) -> (ChainEpoch, ChainEpoch) {
(180 * EPOCHS_IN_DAY, 540 * EPOCHS_IN_DAY)
(180 * EPOCHS_IN_DAY, 1278 * EPOCHS_IN_DAY)
}

pub(super) fn deal_price_per_epoch_bounds(
Expand Down
2 changes: 1 addition & 1 deletion runtime/src/runtime/policy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ pub mod policy_constants {
/// Maximum number of epochs past the current epoch a sector may be set to expire.
/// The actual maximum extension will be the minimum of CurrEpoch + MaximumSectorExpirationExtension
/// and sector.ActivationEpoch+sealProof.SectorMaximumLifetime()
pub const MAX_SECTOR_EXPIRATION_EXTENSION: i64 = 540 * EPOCHS_IN_DAY;
pub const MAX_SECTOR_EXPIRATION_EXTENSION: i64 = 1278 * EPOCHS_IN_DAY;

/// Ratio of sector size to maximum deals per sector.
/// The maximum number of deals is the sector size divided by this number (2^27)
Expand Down
234 changes: 211 additions & 23 deletions test_vm/tests/extend_sectors_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ fn extend<BS: Blockstore>(
partition_index: u64,
sector_number: SectorNumber,
new_expiration: ChainEpoch,
power_update_params: IpldBlock,
power_update_params: Option<IpldBlock>,
v2: bool,
) {
let extension_method = match v2 {
Expand Down Expand Up @@ -99,27 +99,32 @@ fn extend<BS: Blockstore>(
}
};

let mut expect_invoke = vec![
ExpectInvocation {
to: REWARD_ACTOR_ADDR,
method: RewardMethod::ThisEpochReward as u64,
..Default::default()
},
ExpectInvocation {
to: STORAGE_POWER_ACTOR_ADDR,
method: PowerMethod::CurrentTotalPower as u64,
..Default::default()
},
];

if power_update_params.is_some() {
expect_invoke.push(ExpectInvocation {
to: STORAGE_POWER_ACTOR_ADDR,
method: PowerMethod::UpdateClaimedPower as u64,
params: Some(power_update_params),
..Default::default()
});
}

ExpectInvocation {
to: maddr,
method: extension_method,
subinvocs: Some(vec![
ExpectInvocation {
to: REWARD_ACTOR_ADDR,
method: RewardMethod::ThisEpochReward as u64,
..Default::default()
},
ExpectInvocation {
to: STORAGE_POWER_ACTOR_ADDR,
method: PowerMethod::CurrentTotalPower as u64,
..Default::default()
},
ExpectInvocation {
to: STORAGE_POWER_ACTOR_ADDR,
method: PowerMethod::UpdateClaimedPower as u64,
params: Some(Some(power_update_params)),
..Default::default()
},
]),
subinvocs: Some(expect_invoke),
..Default::default()
}
.matches(v.take_invocations().last().unwrap());
Expand Down Expand Up @@ -244,8 +249,7 @@ fn extend_legacy_sector_with_deals_inner(do_extend2: bool) {
);

// Advance halfway through life and extend another 6 months. We need to spread the remaining 90
// days of 10x power over 90 + 180 days.
//
// days of 10x power over 90 + 180 days
// subtract half the remaining deal weight:
// - verified deal weight /= 2
//
Expand Down Expand Up @@ -280,7 +284,7 @@ fn extend_legacy_sector_with_deals_inner(do_extend2: bool) {
partition_index,
sector_number,
new_expiration,
expected_update_claimed_power_params_ser,
Some(expected_update_claimed_power_params_ser),
do_extend2,
);

Expand Down Expand Up @@ -326,7 +330,7 @@ fn extend_legacy_sector_with_deals_inner(do_extend2: bool) {
partition_index,
sector_number,
new_expiration,
expected_update_claimed_power_params_ser,
Some(expected_update_claimed_power_params_ser),
do_extend2,
);

Expand Down Expand Up @@ -575,3 +579,187 @@ fn extend_updated_sector_with_claim() {
sector_info_after_update.expected_day_reward
);
}

#[test]
fn extend_sector_up_to_max_relative_extension() {
let store = MemoryBlockstore::new();
let v = TestVM::<MemoryBlockstore>::new_with_singletons(&store);
let addrs = create_accounts(&v, 3, &TokenAmount::from_whole(10_000));
let seal_proof = RegisteredSealProof::StackedDRG32GiBV1P1;
let (owner, worker) = (addrs[0], addrs[0]);
let sector_number: SectorNumber = 100;
let policy = Policy::default();

// create miner
let miner_id = create_miner(
&v,
&owner,
&worker,
seal_proof.registered_window_post_proof().unwrap(),
&TokenAmount::from_whole(1_000),
)
.0;
let v = v.with_epoch(200);

//
// Precommit, prove and PoSt empty sector (more fully tested in TestCommitPoStFlow)
//
let sector_start =
v.epoch() + max_prove_commit_duration(&Policy::default(), seal_proof).unwrap();

miner_precommit_sector(
&v,
&worker,
&miner_id,
seal_proof,
sector_number,
vec![],
sector_start + 180 * EPOCHS_IN_DAY,
);

// advance time to max seal duration and prove the sector
advance_by_deadline_to_epoch(&v, &miner_id, sector_start);
miner_prove_sector(&v, &worker, &miner_id, sector_number);
// trigger cron to validate the prove commit
cron_tick(&v);

// inspect sector info
let mut miner_state = v.get_state::<MinerState>(&miner_id).unwrap();
let mut sector_info = miner_state.get_sector(&store, sector_number).unwrap().unwrap();
assert_eq!(180 * EPOCHS_IN_DAY, sector_info.expiration - sector_info.activation);

// advance to proving period and submit post
let (deadline_info, partition_index) =
advance_to_proving_deadline(&v, &miner_id, sector_number);

let expected_power_delta =
PowerPair { raw: StoragePower::from(32u64 << 30), qa: StoragePower::from(32u64 << 30) };

submit_windowed_post(
&v,
&worker,
&miner_id,
deadline_info,
partition_index,
Some(expected_power_delta),
);

// move forward one deadline so advanceWhileProving doesn't fail double submitting posts
advance_by_deadline_to_index(
&v,
&miner_id,
deadline_info.index + 1 % policy.wpost_period_deadlines,
);

// Extend the sector by the max relative extension.
let new_expiration = v.epoch() + policy.max_sector_expiration_extension;

extend(
&v,
worker,
miner_id,
deadline_info.index,
partition_index,
sector_number,
new_expiration,
None,
false,
);

miner_state = v.get_state::<MinerState>(&miner_id).unwrap();
sector_info = miner_state.get_sector(&store, sector_number).unwrap().unwrap();
assert_eq!(policy.max_sector_expiration_extension, sector_info.expiration - v.epoch());
}

#[test]
fn commit_sector_with_max_duration_deal() {
let store = MemoryBlockstore::new();
let v = TestVM::<MemoryBlockstore>::new_with_singletons(&store);
let addrs = create_accounts(&v, 3, &TokenAmount::from_whole(10_000));
let seal_proof = RegisteredSealProof::StackedDRG32GiBV1P1;
let (owner, worker, verifier, verified_client) = (addrs[0], addrs[0], addrs[1], addrs[2]);
let sector_number: SectorNumber = 100;
let policy = Policy::default();

// create miner
let miner_id = create_miner(
&v,
&owner,
&worker,
seal_proof.registered_window_post_proof().unwrap(),
&TokenAmount::from_whole(1_000),
)
.0;
let v = v.with_epoch(200);

//
// publish verified deals
//

// register verifier then verified client
let datacap = StoragePower::from(32_u128 << 40);
verifreg_add_verifier(&v, &verifier, datacap.clone());
verifreg_add_client(&v, &verifier, &verified_client, datacap);

// add market collateral for clients and miner
market_add_balance(&v, &verified_client, &verified_client, &TokenAmount::from_whole(3));
market_add_balance(&v, &worker, &miner_id, &TokenAmount::from_whole(64));

let deal_lifetime = policy.max_sector_expiration_extension
- max_prove_commit_duration(&policy, seal_proof).unwrap_or_default();
// create 1 verified deal for total sector capacity for 6 months
let deal_start = v.epoch() + max_prove_commit_duration(&Policy::default(), seal_proof).unwrap();
let deals = market_publish_deal(
&v,
&worker,
&verified_client,
&miner_id,
"deal1".to_string(),
PaddedPieceSize(32u64 << 30),
true,
deal_start,
deal_lifetime,
)
.ids;

//
// Precommit, prove and PoSt empty sector (more fully tested in TestCommitPoStFlow)
//
miner_precommit_sector(
&v,
&worker,
&miner_id,
seal_proof,
sector_number,
deals,
deal_start + deal_lifetime,
);

// advance time to max seal duration and prove the sector
advance_by_deadline_to_epoch(&v, &miner_id, deal_start);
miner_prove_sector(&v, &worker, &miner_id, sector_number);
// trigger cron to validate the prove commit
cron_tick(&v);

// advance to proving period and submit post
let (deadline_info, partition_index) =
advance_to_proving_deadline(&v, &miner_id, sector_number);

let expected_power_delta = PowerPair {
raw: StoragePower::from(32u64 << 30),
qa: 10 * StoragePower::from(32u64 << 30),
};

submit_windowed_post(
&v,
&worker,
&miner_id,
deadline_info,
partition_index,
Some(expected_power_delta),
);
// inspect sector info
let miner_state = v.get_state::<MinerState>(&miner_id).unwrap();
let sector_info = miner_state.get_sector(&store, sector_number).unwrap().unwrap();
assert_eq!(deal_lifetime, sector_info.expiration - sector_info.activation);
}
57 changes: 56 additions & 1 deletion test_vm/tests/publish_deals_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,7 @@ fn psd_bad_sig() {
};

let invalid_sig_bytes = "very_invalid_sig".as_bytes().to_vec();

let publish_params = PublishStorageDealsParams {
deals: vec![ClientDealProposal {
proposal: proposal.clone(),
Expand All @@ -522,7 +523,6 @@ fn psd_bad_sig() {
},
}],
};

let ret = v
.apply_message(
&a.worker,
Expand Down Expand Up @@ -594,6 +594,61 @@ fn psd_all_deals_are_good() {
v.assert_state_invariants();
}

#[test]
fn psd_valid_deals_with_ones_longer_than_540() {
let store = MemoryBlockstore::new();
let (v, a, deal_start) = setup(&store);
let mut batcher =
DealBatcher::new(&v, a.maddr, PaddedPieceSize(1 << 30), false, deal_start, DEAL_LIFETIME);

// good deals
batcher.stage(
a.client1,
"deal0",
DealOptions { deal_lifetime: Option::from(541 * EPOCHS_IN_DAY), ..Default::default() },
);
batcher.stage(
a.client1,
"deal1",
DealOptions { deal_lifetime: Option::from(1278 * EPOCHS_IN_DAY), ..Default::default() },
);
batcher.stage(a.client1, "deal2", DealOptions::default());

let deal_ret = batcher.publish_ok(a.worker);
let good_inputs = bf_all(deal_ret.valid_deals);
assert_eq!(vec![0, 1, 2], good_inputs);
v.assert_state_invariants();
}

#[test]
fn psd_deal_duration_too_long() {
let store = MemoryBlockstore::new();
let (v, a, deal_start) = setup(&store);
let mut batcher =
DealBatcher::new(&v, a.maddr, PaddedPieceSize(1 << 30), false, deal_start, DEAL_LIFETIME);

// good deals
batcher.stage(
a.client1,
"deal0",
DealOptions { deal_lifetime: Option::from(541 * EPOCHS_IN_DAY), ..Default::default() },
);

batcher.stage(a.client1, "deal1", DealOptions::default());

//bad deal - duration > max deal
batcher.stage(
a.client1,
"deal2",
DealOptions { deal_lifetime: Option::from(1279 * EPOCHS_IN_DAY), ..Default::default() },
);

let deal_ret = batcher.publish_ok(a.worker);
let good_inputs = bf_all(deal_ret.valid_deals);
assert_eq!(vec![0, 1], good_inputs);
v.assert_state_invariants();
}

#[derive(Clone, Default)]
struct DealOptions {
provider: Option<Address>,
Expand Down

0 comments on commit f28bfd0

Please sign in to comment.