Skip to content

Commit

Permalink
Baseline bug fix (FIP-0081) (#1557)
Browse files Browse the repository at this point in the history
* initial updates to integrate baseline bug fix

* moving ramp duration to be returned by call to total_power rather than a separate function

* updated to use correct variable name

* changing type to i64 so that the ramp can be preplanned

* updated state to store epoch at which upgrade will happen, and the duration, and refactored other variables to set the correct inputs for the pledge function

* fixed syntax and type errors indicated by running make check

* fixed make check errors

* fixing rustfmt errors

* fixing additional rustfmt errors

* fixed integration test errors

* write three tests, fix bug in pledge calculation

* remove unnecessary TODO items

* remote yet another unnecessary TODO item

* document the two new fields in power state

* test pre-ramp, test early on-ramp

* check first step on ramp

* use if-then-else rather than min/max

* avoid a division when merging baseline and simple pledges

* validate pledges 1 epoch around FIP0081 activation

* rename gamme constant, reword comments

* test more FIP0081 cases

* move tests to separate file

* correct test comments

---------

Co-authored-by: David Himmelstrup <[email protected]>
Co-authored-by: lemmih <[email protected]>
  • Loading branch information
3 people authored Sep 30, 2024
1 parent 76b4765 commit 01a05fc
Show file tree
Hide file tree
Showing 12 changed files with 318 additions and 3 deletions.
2 changes: 2 additions & 0 deletions actors/market/src/ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,5 +162,7 @@ pub mod power {
pub quality_adj_power: StoragePower,
pub pledge_collateral: TokenAmount,
pub quality_adj_power_smoothed: FilterEstimate,
pub ramp_start_epoch: i64,
pub ramp_duration_epochs: u64,
}
}
2 changes: 2 additions & 0 deletions actors/market/tests/harness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1150,6 +1150,8 @@ pub fn expect_query_network_info(rt: &MockRuntime) {
quality_adj_power: power.clone(),
pledge_collateral: TokenAmount::default(),
quality_adj_power_smoothed: FilterEstimate::new(reward.atto().clone(), BigInt::zero()),
ramp_start_epoch: 0,
ramp_duration_epochs: 0,
};
let current_reward = ThisEpochRewardReturn {
this_epoch_baseline_power: power,
Expand Down
2 changes: 2 additions & 0 deletions actors/miner/src/ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ pub mod power {
pub quality_adj_power: StoragePower,
pub pledge_collateral: TokenAmount,
pub quality_adj_power_smoothed: FilterEstimate,
pub ramp_start_epoch: i64,
pub ramp_duration_epochs: u64,
}
#[derive(Serialize_tuple, Deserialize_tuple)]
pub struct EnrollCronEventParams {
Expand Down
18 changes: 18 additions & 0 deletions actors/miner/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -817,6 +817,8 @@ impl Actor {
network_baseline: rew.this_epoch_baseline_power,
circulating_supply,
epoch_reward: rew.this_epoch_reward_smoothed,
epochs_since_ramp_start: rt.curr_epoch() - pwr.ramp_start_epoch,
ramp_duration_epochs: pwr.ramp_duration_epochs,
};

/*
Expand Down Expand Up @@ -1908,6 +1910,8 @@ impl Actor {
network_baseline: rew.this_epoch_baseline_power,
circulating_supply,
epoch_reward: rew.this_epoch_reward_smoothed,
epochs_since_ramp_start: rt.curr_epoch() - pwr.ramp_start_epoch,
ramp_duration_epochs: pwr.ramp_duration_epochs,
};
activate_new_sector_infos(
rt,
Expand Down Expand Up @@ -1981,6 +1985,8 @@ impl Actor {
network_baseline: params.reward_baseline_power,
circulating_supply: rt.total_fil_circ_supply(),
epoch_reward: params.reward_smoothed,
epochs_since_ramp_start: 0,
ramp_duration_epochs: 0,
};
activate_new_sector_infos(
rt,
Expand Down Expand Up @@ -2093,6 +2099,8 @@ impl Actor {
network_baseline: rew.this_epoch_baseline_power,
circulating_supply,
epoch_reward: rew.this_epoch_reward_smoothed,
epochs_since_ramp_start: rt.curr_epoch() - pwr.ramp_start_epoch,
ramp_duration_epochs: pwr.ramp_duration_epochs,
};

let sector_day_reward = expected_reward_for_power(
Expand All @@ -2115,6 +2123,8 @@ impl Actor {
&pledge_inputs.epoch_reward,
&pledge_inputs.network_qap,
&pledge_inputs.circulating_supply,
pledge_inputs.epochs_since_ramp_start,
pledge_inputs.ramp_duration_epochs,
);

let sectors_to_add = valid_sectors
Expand Down Expand Up @@ -4116,6 +4126,8 @@ where
network_baseline: rew.this_epoch_baseline_power,
circulating_supply,
epoch_reward: rew.this_epoch_reward_smoothed,
epochs_since_ramp_start: rt.curr_epoch() - pow.ramp_start_epoch,
ramp_duration_epochs: pow.ramp_duration_epochs,
};
let mut power_delta = PowerPair::zero();
let mut pledge_delta = TokenAmount::zero();
Expand Down Expand Up @@ -4307,6 +4319,8 @@ fn update_existing_sector_info(
&pledge_inputs.epoch_reward,
&pledge_inputs.network_qap,
&pledge_inputs.circulating_supply,
pledge_inputs.epochs_since_ramp_start,
pledge_inputs.ramp_duration_epochs,
),
);
new_sector_info
Expand Down Expand Up @@ -5546,6 +5560,8 @@ fn activate_new_sector_infos(
&pledge_inputs.epoch_reward,
&pledge_inputs.network_qap,
&pledge_inputs.circulating_supply,
pledge_inputs.epochs_since_ramp_start,
pledge_inputs.ramp_duration_epochs,
);

deposit_to_unlock += pci.pre_commit_deposit.clone();
Expand Down Expand Up @@ -5958,6 +5974,8 @@ struct NetworkPledgeInputs {
pub network_baseline: StoragePower,
pub circulating_supply: TokenAmount,
pub epoch_reward: FilterEstimate,
pub epochs_since_ramp_start: i64,
pub ramp_duration_epochs: u64,
}

// Note: probably better to push this one level down into state
Expand Down
41 changes: 38 additions & 3 deletions actors/miner/src/monies.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ pub const TERMINATION_LIFETIME_CAP: ChainEpoch = 140;
// Multiplier of whole per-winner rewards for a consensus fault penalty.
const CONSENSUS_FAULT_FACTOR: u64 = 5;

const GAMMA_FIXED_POINT_FACTOR: u64 = 1000; // 3 decimal places

/// The projected block reward a sector would earn over some period.
/// Also known as "BR(t)".
/// BR(t) = ProjectedRewardFraction(t) * SectorQualityAdjustedPower
Expand Down Expand Up @@ -255,6 +257,8 @@ pub fn initial_pledge_for_power(
reward_estimate: &FilterEstimate,
network_qa_power_estimate: &FilterEstimate,
circulating_supply: &TokenAmount,
epochs_since_ramp_start: i64,
ramp_duration_epochs: u64,
) -> TokenAmount {
let ip_base = expected_reward_for_power_clamped_at_atto_fil(
reward_estimate,
Expand All @@ -267,10 +271,41 @@ pub fn initial_pledge_for_power(
let lock_target_denom = LOCK_TARGET_FACTOR_DENOM;
let pledge_share_num = qa_power;
let network_qa_power = network_qa_power_estimate.estimate();
let pledge_share_denom = cmp::max(cmp::max(&network_qa_power, baseline_power), qa_power);

// Once FIP-0081 has fully activated, additional pledge will be 70% baseline
// pledge + 30% simple pledge.
const FIP_0081_ACTIVATION_PERMILLE: i64 = 300;
// Gamma/GAMMA_FIXED_POINT_FACTOR is the share of pledge coming from the
// baseline formulation, with 1-(gamma/GAMMA_FIXED_POINT_FACTOR) coming from
// simple pledge.
// gamma = 1000 - 300 * (epochs_since_ramp_start / ramp_duration_epochs).max(0).min(1)
let skew = if epochs_since_ramp_start < 0 {
// No skew before ramp start
0
} else if ramp_duration_epochs == 0 || epochs_since_ramp_start >= ramp_duration_epochs as i64 {
// 100% skew after ramp end
FIP_0081_ACTIVATION_PERMILLE as u64
} else {
((epochs_since_ramp_start * FIP_0081_ACTIVATION_PERMILLE) / ramp_duration_epochs as i64)
as u64
};
let gamma = GAMMA_FIXED_POINT_FACTOR - skew;

let additional_ip_num = lock_target_num * pledge_share_num;
let additional_ip_denom = pledge_share_denom * lock_target_denom;
let additional_ip = additional_ip_num.div_floor(&additional_ip_denom);

let pledge_share_denom_baseline =
cmp::max(cmp::max(&network_qa_power, baseline_power), qa_power);
let pledge_share_denom_simple = cmp::max(&network_qa_power, qa_power);

let additional_ip_denom_baseline = pledge_share_denom_baseline * lock_target_denom;
let additional_ip_baseline = (gamma * &additional_ip_num)
.div_floor(&(additional_ip_denom_baseline * GAMMA_FIXED_POINT_FACTOR));
let additional_ip_denom_simple = pledge_share_denom_simple * lock_target_denom;
let additional_ip_simple = ((GAMMA_FIXED_POINT_FACTOR - gamma) * &additional_ip_num)
.div_floor(&(additional_ip_denom_simple * GAMMA_FIXED_POINT_FACTOR));

// convex combination of simple and baseline pledge
let additional_ip = additional_ip_baseline + additional_ip_simple;

let nominal_pledge = ip_base + TokenAmount::from_atto(additional_ip);
let pledge_cap = TokenAmount::from_atto(INITIAL_PLEDGE_MAX_PER_BYTE.atto() * qa_power);
Expand Down
3 changes: 3 additions & 0 deletions actors/miner/tests/aggregate_prove_commit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@ fn valid_precommits_then_aggregate_provecommit() {
&actor.epoch_reward_smooth,
&actor.epoch_qa_power_smooth,
&rt.total_fil_circ_supply(),
// NOTE: zero inputs here preserve the original pledge functionality
0,
0,
);
let ten_sectors_initial_pledge = BigInt::from(10i32) * expected_initial_pledge.clone();
assert_eq!(ten_sectors_initial_pledge, st.initial_pledge);
Expand Down
Loading

0 comments on commit 01a05fc

Please sign in to comment.