Skip to content

Commit a754089

Browse files
committed
WIP: Use vest_funds instead of the new create_deposit state to manage create miner deposit
1 parent be3d556 commit a754089

File tree

18 files changed

+255
-573
lines changed

18 files changed

+255
-573
lines changed

actors/miner/src/lib.rs

Lines changed: 57 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ pub use expiration_queue::*;
4646
use fil_actors_runtime::cbor::{serialize, serialize_vec};
4747
use fil_actors_runtime::reward::{FilterEstimate, ThisEpochRewardReturn};
4848
use fil_actors_runtime::runtime::builtins::Type;
49-
use fil_actors_runtime::runtime::policy_constants::MAX_SECTOR_NUMBER;
49+
use fil_actors_runtime::runtime::policy_constants::{MAX_SECTOR_NUMBER, MINIMUM_CONSENSUS_POWER};
5050
use fil_actors_runtime::runtime::{ActorCode, DomainSeparationTag, Policy, Runtime};
5151
use fil_actors_runtime::{
5252
actor_dispatch, actor_error, deserialize_block, extract_send_result, util, ActorContext,
@@ -155,7 +155,6 @@ pub enum Method {
155155
GetVestingFundsExported = frc42_dispatch::method_hash!("GetVestingFunds"),
156156
GetPeerIDExported = frc42_dispatch::method_hash!("GetPeerID"),
157157
GetMultiaddrsExported = frc42_dispatch::method_hash!("GetMultiaddrs"),
158-
LockCreateMinerDepositExported = frc42_dispatch::method_hash!("LockCreateMinerDeposit"),
159158
}
160159

161160
pub const SECTOR_CONTENT_CHANGED: MethodNum = frc42_dispatch::method_hash!("SectorContentChanged");
@@ -181,6 +180,14 @@ impl Actor {
181180
check_peer_info(rt.policy(), &params.peer_id, &params.multi_addresses)?;
182181
check_valid_post_proof_type(rt.policy(), params.window_post_proof_type)?;
183182

183+
let balance = rt.current_balance();
184+
let deposit = calculate_create_miner_deposit(rt, params.network_qap)?;
185+
if balance < deposit {
186+
return Err(actor_error!(insufficient_funds;
187+
"not enough balance to lock for create miner deposit: \
188+
sent balance {} < deposit {}", balance.atto(), deposit.atto()));
189+
}
190+
184191
let owner = rt.resolve_address(&params.owner).ok_or_else(|| {
185192
actor_error!(illegal_argument, "unable to resolve owner address: {}", params.owner)
186193
})?;
@@ -239,7 +246,10 @@ impl Actor {
239246
e.downcast_default(ExitCode::USR_ILLEGAL_STATE, "failed to construct illegal state")
240247
})?;
241248

242-
let st = State::new(policy, rt.store(), info_cid, period_start, deadline_idx)?;
249+
let store = rt.store();
250+
let mut st = State::new(policy, store, info_cid, period_start, deadline_idx)?;
251+
st.add_locked_funds(store, rt.curr_epoch(), &deposit, &REWARD_VESTING_SPEC)
252+
.map_err(|e| actor_error!(illegal_state, e))?;
243253
rt.create(&st)?;
244254
Ok(())
245255
}
@@ -311,12 +321,7 @@ impl Actor {
311321
let vesting_funds = state
312322
.load_vesting_funds(rt.store())
313323
.map_err(|e| actor_error!(illegal_state, "failed to load vesting funds: {}", e))?;
314-
let mut ret = vesting_funds.funds.into_iter().map(|v| (v.epoch, v.amount)).collect_vec();
315-
316-
// add create miner deposit into vest table
317-
if let Some(CreateMinerDeposit { amount, epoch }) = &state.create_miner_deposit {
318-
ret.push((*epoch, amount.clone()));
319-
}
324+
let ret = vesting_funds.funds.into_iter().map(|v| (v.epoch, v.amount)).collect_vec();
320325

321326
Ok(GetVestingFundsReturn { vesting_funds: ret })
322327
}
@@ -3425,20 +3430,6 @@ impl Actor {
34253430
state.check_balance_invariants(&rt.current_balance()).map_err(balance_invariants_broken)?;
34263431
Ok(())
34273432
}
3428-
3429-
/// Lock the create miner deposit for 180 days.
3430-
/// See FIP-0077, https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0077.md
3431-
fn lock_create_miner_deposit(
3432-
rt: &impl Runtime,
3433-
params: LockCreateMinerDepositParams,
3434-
) -> Result<(), ActorError> {
3435-
rt.validate_immediate_caller_is(std::iter::once(&STORAGE_POWER_ACTOR_ADDR))?;
3436-
rt.transaction(|st: &mut State, rt| {
3437-
st.add_create_miner_deposit(params.amount, rt.curr_epoch());
3438-
3439-
Ok(())
3440-
})
3441-
}
34423433
}
34433434

34443435
#[derive(Debug, PartialEq, Clone)]
@@ -4973,7 +4964,6 @@ fn resolve_worker_address(rt: &impl Runtime, raw: Address) -> Result<ActorID, Ac
49734964
}
49744965

49754966
fn burn_funds(rt: &impl Runtime, amount: TokenAmount) -> Result<(), ActorError> {
4976-
log::debug!("storage provder {} burning {}", rt.message().receiver(), amount);
49774967
if amount.is_positive() {
49784968
extract_send_result(rt.send_simple(&BURNT_FUNDS_ACTOR_ADDR, METHOD_SEND, None, amount))?;
49794969
}
@@ -5378,6 +5368,49 @@ fn activate_new_sector_infos(
53785368
Ok(())
53795369
}
53805370

5371+
/// Calculate create miner deposit by MINIMUM_CONSENSUS_POWER x StateMinerInitialPledgeCollateral
5372+
/// See FIP-0077, https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0077.md
5373+
pub fn calculate_create_miner_deposit(
5374+
rt: &impl Runtime,
5375+
network_qap: FilterEstimate,
5376+
) -> Result<TokenAmount, ActorError> {
5377+
// set network pledge inputs
5378+
let rew = request_current_epoch_block_reward(rt)?;
5379+
let circulating_supply = rt.total_fil_circ_supply();
5380+
let pledge_inputs = NetworkPledgeInputs {
5381+
network_qap,
5382+
network_baseline: rew.this_epoch_baseline_power,
5383+
circulating_supply,
5384+
epoch_reward: rew.this_epoch_reward_smoothed,
5385+
};
5386+
5387+
/// set sector size with min power
5388+
#[cfg(feature = "min-power-2k")]
5389+
let sector_size = SectorSize::_2KiB;
5390+
#[cfg(feature = "min-power-2g")]
5391+
let sector_size = SectorSize::_8MiB;
5392+
#[cfg(feature = "min-power-32g")]
5393+
let sector_size = SectorSize::_512MiB;
5394+
#[cfg(not(any(
5395+
feature = "min-power-2k",
5396+
feature = "min-power-2g",
5397+
feature = "min-power-32g"
5398+
)))]
5399+
let sector_size = SectorSize::_32GiB;
5400+
5401+
let sector_number = MINIMUM_CONSENSUS_POWER / sector_size as i64;
5402+
let power =
5403+
qa_power_for_weight(sector_size, MIN_SECTOR_EXPIRATION, &BigInt::zero(), &BigInt::zero());
5404+
let sector_initial_pledge = initial_pledge_for_power(
5405+
&power,
5406+
&pledge_inputs.network_baseline,
5407+
&pledge_inputs.epoch_reward,
5408+
&pledge_inputs.network_qap,
5409+
&pledge_inputs.circulating_supply,
5410+
);
5411+
Ok(sector_initial_pledge * sector_number)
5412+
}
5413+
53815414
pub struct SectorPiecesActivationInput {
53825415
pub piece_manifests: Vec<PieceActivationManifest>,
53835416
pub sector_expiry: ChainEpoch,
@@ -5766,7 +5799,6 @@ impl ActorCode for Actor {
57665799
GetMultiaddrsExported => get_multiaddresses,
57675800
ProveCommitSectors3 => prove_commit_sectors3,
57685801
ProveReplicaUpdates3 => prove_replica_updates3,
5769-
LockCreateMinerDepositExported => lock_create_miner_deposit,
57705802
}
57715803
}
57725804

actors/miner/src/state.rs

Lines changed: 3 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,6 @@ pub struct State {
7272
/// Sum of initial pledge requirements of all active sectors.
7373
pub initial_pledge: TokenAmount,
7474

75-
/// amount of create miner depoist and when it should be unlocked.
76-
pub create_miner_deposit: Option<CreateMinerDeposit>,
77-
7875
/// Sectors that have been pre-committed but not yet proven.
7976
/// Map, HAMT<SectorNumber, SectorPreCommitOnChainInfo>
8077
pub pre_committed_sectors: Cid,
@@ -192,7 +189,6 @@ impl State {
192189
early_terminations: BitField::new(),
193190
deadline_cron_active: false,
194191
pre_committed_sectors_cleanup: empty_precommits_cleanup_array,
195-
create_miner_deposit: None,
196192
})
197193
}
198194

@@ -761,22 +757,11 @@ impl State {
761757
Ok(())
762758
}
763759

764-
// Return true when the miner actor needs to continue scheduling deadline crons
765-
pub fn continue_deadline_cron_without_create_miner_deposit(&self) -> bool {
766-
!self.pre_commit_deposits.is_zero()
767-
|| !self.initial_pledge.is_zero()
768-
|| !self.locked_funds.is_zero()
769-
}
770-
771760
// Return true when the miner actor needs to continue scheduling deadline crons
772761
pub fn continue_deadline_cron(&self) -> bool {
773762
!self.pre_commit_deposits.is_zero()
774763
|| !self.initial_pledge.is_zero()
775764
|| !self.locked_funds.is_zero()
776-
|| !self
777-
.create_miner_deposit
778-
.as_ref()
779-
.map_or_else(|| true, |deposit| deposit.amount.is_zero())
780765
}
781766

782767
//
@@ -820,15 +805,6 @@ impl State {
820805
}
821806
}
822807

823-
// Unlocked after 180 days.
824-
pub fn add_create_miner_deposit(&mut self, amount: TokenAmount, curr_epoch: ChainEpoch) {
825-
let deposit = CreateMinerDeposit {
826-
amount,
827-
epoch: (180 * fil_actors_runtime::EPOCHS_IN_DAY) + curr_epoch,
828-
};
829-
self.create_miner_deposit = Some(deposit);
830-
}
831-
832808
/// First vests and unlocks the vested funds AND then locks the given funds in the vesting table.
833809
pub fn add_locked_funds<BS: Blockstore>(
834810
&mut self,
@@ -854,13 +830,6 @@ impl State {
854830
));
855831
}
856832

857-
// unlock create miner deposit
858-
if let Some(depoist) = &self.create_miner_deposit {
859-
if depoist.epoch <= current_epoch {
860-
self.create_miner_deposit.take();
861-
}
862-
}
863-
864833
// add locked funds now
865834
vesting_funds.add_locked_funds(current_epoch, vesting_sum, self.proving_period_start, spec);
866835
self.locked_funds += vesting_sum;
@@ -957,20 +926,12 @@ impl State {
957926
store: &BS,
958927
current_epoch: ChainEpoch,
959928
) -> anyhow::Result<TokenAmount> {
960-
let mut amount_unlocked = TokenAmount::zero();
961-
if let Some(depoist) = &self.create_miner_deposit {
962-
if depoist.epoch <= current_epoch {
963-
amount_unlocked += &depoist.amount;
964-
self.create_miner_deposit.take();
965-
}
966-
}
967-
968929
if self.locked_funds.is_zero() {
969930
return Ok(TokenAmount::zero());
970931
}
971932

972933
let mut vesting_funds = self.load_vesting_funds(store)?;
973-
amount_unlocked += vesting_funds.unlock_vested_funds(current_epoch);
934+
let amount_unlocked = vesting_funds.unlock_vested_funds(current_epoch);
974935
self.locked_funds -= &amount_unlocked;
975936
if self.locked_funds.is_negative() {
976937
return Err(anyhow!(
@@ -999,13 +960,9 @@ impl State {
999960

1000961
/// Unclaimed funds that are not locked -- includes funds used to cover initial pledge requirement.
1001962
pub fn get_unlocked_balance(&self, actor_balance: &TokenAmount) -> anyhow::Result<TokenAmount> {
1002-
let mut unlocked_balance =
963+
let unlocked_balance =
1003964
actor_balance - &self.locked_funds - &self.pre_commit_deposits - &self.initial_pledge;
1004965

1005-
if let Some(depoist) = &self.create_miner_deposit {
1006-
unlocked_balance -= &depoist.amount;
1007-
}
1008-
1009966
if unlocked_balance.is_negative() {
1010967
return Err(anyhow!("negative unlocked balance {}", unlocked_balance));
1011968
}
@@ -1036,15 +993,8 @@ impl State {
1036993
return Err(anyhow!("fee debt is negative: {}", self.fee_debt));
1037994
}
1038995

1039-
let mut min_balance = &self.pre_commit_deposits + &self.locked_funds + &self.initial_pledge;
996+
let min_balance = &self.pre_commit_deposits + &self.locked_funds + &self.initial_pledge;
1040997

1041-
if let Some(CreateMinerDeposit { amount, .. }) = &self.create_miner_deposit {
1042-
if amount.is_negative() {
1043-
return Err(anyhow!("create miner deposit is negative: {}", amount));
1044-
}
1045-
1046-
min_balance += amount;
1047-
}
1048998
if balance < &min_balance {
1049999
return Err(anyhow!("fee debt is negative: {}", self.fee_debt));
10501000
}
@@ -1239,13 +1189,6 @@ impl State {
12391189
}
12401190
}
12411191

1242-
#[derive(Serialize_tuple, Deserialize_tuple, Clone, Debug)]
1243-
pub struct CreateMinerDeposit {
1244-
pub amount: TokenAmount,
1245-
/// when to unlock
1246-
pub epoch: ChainEpoch,
1247-
}
1248-
12491192
pub struct AdvanceDeadlineResult {
12501193
pub pledge_delta: TokenAmount,
12511194
pub power_delta: PowerPair,

actors/miner/src/testing.rs

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -248,11 +248,6 @@ fn check_miner_balances<BS: Blockstore>(
248248
balance: &TokenAmount,
249249
acc: &MessageAccumulator,
250250
) {
251-
let create_deposit = state
252-
.create_miner_deposit
253-
.as_ref()
254-
.map_or_else(|| TokenAmount::zero(), |deposit| deposit.amount.clone());
255-
256251
acc.require(
257252
!balance.is_negative(),
258253
format!("miner actor balance is less than zero: {balance}"),
@@ -273,11 +268,7 @@ fn check_miner_balances<BS: Blockstore>(
273268
!state.fee_debt.is_negative(),
274269
format!("miner fee debt is less than zero: {}", state.fee_debt),
275270
);
276-
acc.require(
277-
!create_deposit.is_negative(),
278-
format!("create miner deposit is less than zero: {}", create_deposit),
279-
);
280-
acc.require(!(balance - &state.locked_funds - &state.pre_commit_deposits - &state.initial_pledge - &create_deposit).is_negative(), format!("miner balance {balance} is less than sum of locked funds ({}), precommit deposit ({}), initial pledge ({}) and create miner deposit ({})", state.locked_funds, state.pre_commit_deposits, state.initial_pledge, create_deposit));
271+
acc.require(!(balance - &state.locked_funds - &state.pre_commit_deposits - &state.initial_pledge).is_negative(), format!("miner balance {balance} is less than sum of locked funds ({}), precommit deposit ({}), initial pledge ({})", state.locked_funds, state.pre_commit_deposits, state.initial_pledge));
281272

282273
// locked funds must be sum of vesting table and vesting table payments must be quantized
283274
let mut vesting_sum = TokenAmount::zero();
@@ -315,7 +306,7 @@ fn check_miner_balances<BS: Blockstore>(
315306
);
316307

317308
// non zero funds implies that DeadlineCronActive is true
318-
if state.continue_deadline_cron_without_create_miner_deposit() {
309+
if state.continue_deadline_cron() {
319310
acc.require(state.deadline_cron_active, "DeadlineCronActive == false when IP+PCD+LF > 0");
320311
}
321312
}

actors/miner/src/types.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ pub struct MinerConstructorParams {
4545
#[serde(with = "strict_bytes")]
4646
pub peer_id: Vec<u8>,
4747
pub multi_addresses: Vec<BytesDe>,
48+
pub network_qap: FilterEstimate,
4849
}
4950

5051
#[derive(Serialize_tuple, Deserialize_tuple)]

actors/miner/tests/apply_rewards.rs

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,6 @@ fn funds_vest() {
4343
let rt = h.new_runtime();
4444
rt.set_balance(BIG_BALANCE.clone());
4545
h.construct_and_verify(&rt);
46-
let st = h.get_state(&rt);
47-
48-
let vesting_funds = st.load_vesting_funds(&rt.store).unwrap();
49-
50-
// Nothing vesting to start
51-
assert!(vesting_funds.funds.is_empty());
52-
assert!(st.locked_funds.is_zero());
5346

5447
// Lock some funds with AddLockedFund
5548
let amt = TokenAmount::from_atto(600_000);
@@ -115,14 +108,13 @@ fn penalty_is_partially_burnt_and_stored_as_fee_debt() {
115108
let st = h.get_state(&rt);
116109
assert!(st.fee_debt.is_zero());
117110

118-
let amt = rt.get_balance();
111+
let amt = BIG_BALANCE.clone();
119112
let penalty = &amt * 3;
120113
let reward = amt.clone();
121114

122115
// manually update actor balance to include the added funds on reward message
123116
let new_balance = &reward + &amt;
124117
rt.set_balance(new_balance);
125-
126118
rt.set_caller(*REWARD_ACTOR_CODE_ID, REWARD_ACTOR_ADDR);
127119
rt.expect_validate_caller_addr(vec![REWARD_ACTOR_ADDR]);
128120

@@ -163,8 +155,6 @@ fn rewards_pay_back_fee_debt() {
163155
h.construct_and_verify(&rt);
164156
let mut st = h.get_state(&rt);
165157

166-
assert!(st.locked_funds.is_zero());
167-
168158
let amt = rt.get_balance();
169159
let available_before = h.get_available_balance(&rt).unwrap();
170160
assert!(available_before.is_positive());

actors/miner/tests/deadline_cron.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@ fn cron_on_inactive_state() {
3030
h.construct_and_verify(&rt);
3131

3232
let st = h.get_state(&rt);
33-
assert_eq!(PERIOD_OFFSET - rt.policy.wpost_proving_period, st.proving_period_start);
34-
assert!(!st.continue_deadline_cron_without_create_miner_deposit());
33+
assert!(!st.continue_deadline_cron());
3534

35+
assert_eq!(PERIOD_OFFSET - rt.policy.wpost_proving_period, st.proving_period_start);
3636
// cron does nothing and does not enroll another cron
3737
let deadline = h.deadline(&rt);
3838
rt.set_epoch(deadline.last());

0 commit comments

Comments
 (0)