Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add miner deposit #1398

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 23 additions & 3 deletions actors/miner/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,10 @@ impl Actor {
.collect::<Result<_, _>>()?;

let policy = rt.policy();
if rt.current_balance() < policy.new_miner_deposit {
return Err(actor_error!(illegal_argument, "not enough miner deposit"));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Insufficient funds is probably a better error code

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, but this may exit two case:
case1: value in message is not enough for new miner deposit
case2: the from address dont have enough funds to deposit this error return before exec create miner.

so i think argument error should be resonable

}

let current_epoch = rt.curr_epoch();
let blake2b = |b: &[u8]| rt.hash_blake2b(b);
let offset =
Expand Down Expand Up @@ -230,12 +234,29 @@ impl Actor {
e.downcast_default(ExitCode::USR_ILLEGAL_STATE, "failed to construct illegal state")
})?;

let st =
let mut st =
State::new(policy, rt.store(), info_cid, period_start, deadline_idx).map_err(|e| {
e.downcast_default(ExitCode::USR_ILLEGAL_STATE, "failed to construct state")
})?;
rt.create(&st)?;

let (new_miner_deposit_to_lock, locked_new_miner_deposit_vesting_spec) =
locked_new_miner_deposit(policy.new_miner_deposit.clone());

_ = st
.add_locked_funds(
rt.store(),
current_epoch,
&new_miner_deposit_to_lock,
locked_new_miner_deposit_vesting_spec,
)
.map_err(|e| {
actor_error!(
illegal_state,
"failed to lock new miner deposit in vesting table: {}",
e
)
})?;
Comment on lines +252 to +258
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use the newer .with_context_code form here.

rt.create(&st)?;
Ok(())
}

Expand Down Expand Up @@ -4013,7 +4034,6 @@ fn handle_proving_deadline(

Ok(state.clone())
})?;

// Remove power for new faults, and burn penalties.
request_update_power(rt, power_delta_total)?;
burn_funds(rt, penalty_total)?;
Expand Down
5 changes: 5 additions & 0 deletions actors/miner/src/monies.rs
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,11 @@ pub fn locked_reward_from_reward(reward: TokenAmount) -> (TokenAmount, &'static
(lock_amount, &REWARD_VESTING_SPEC)
}

/// Lock amount of deposit of creating new miner
pub fn locked_new_miner_deposit(deposit: TokenAmount) -> (TokenAmount, &'static VestSpec) {
(deposit, &REWARD_VESTING_SPEC)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is the deposit a parameter here if it's just passed straight back out?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just copy a copy code from locked_reward_from_reward. In fact, I do tend to use a certain ratio of sector collateral as new miners deposit.

}

const BATCH_DISCOUNT_NUM: u32 = 1;
const BATCH_DISCOUNT_DENOM: u32 = 20;

Expand Down
4 changes: 1 addition & 3 deletions actors/miner/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -766,9 +766,7 @@ impl State {

// Return true when the miner actor needs to continue scheduling deadline crons
pub fn continue_deadline_cron(&self) -> bool {
!self.pre_commit_deposits.is_zero()
|| !self.initial_pledge.is_zero()
|| !self.locked_funds.is_zero()
!self.pre_commit_deposits.is_zero() || !self.initial_pledge.is_zero()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this change is reasonable. A miner needs to keep vesting if they have locked funds - we can't tell how they reached this state.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you are right removing this will cause problems with the circulation calculations.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i have a progessing version without this code, but there are too much test case to fix. and had time to handle this since I quit my job recently.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm, check_state_invariants behavior need change.

if state.continue_deadline_cron() {

}

//
Expand Down
30 changes: 9 additions & 21 deletions actors/miner/tests/apply_rewards.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ use fil_actor_miner::ApplyRewardParams;
use fil_actor_miner::REWARD_VESTING_SPEC;
use fil_actor_miner::{Actor, Method};
use fil_actor_power::Method as PowerMethod;
use fil_actors_runtime::runtime::Runtime;
use fil_actors_runtime::runtime::RuntimePolicy;
use fil_actors_runtime::test_utils::REWARD_ACTOR_CODE_ID;
use fil_actors_runtime::BURNT_FUNDS_ACTOR_ADDR;
use fil_actors_runtime::REWARD_ACTOR_ADDR;
use fil_actors_runtime::STORAGE_POWER_ACTOR_ADDR;
use std::ops::Add;

use fvm_shared::bigint::Zero;
use fvm_shared::clock::{ChainEpoch, QuantSpec};
Expand All @@ -18,7 +18,6 @@ use fvm_shared::METHOD_SEND;

mod util;

use fil_actor_miner::testing::check_state_invariants;
use fvm_ipld_encoding::ipld_block::IpldBlock;
use util::*;

Expand All @@ -34,14 +33,15 @@ fn funds_are_locked() {
let rwd = TokenAmount::from_atto(1_000_000);
h.apply_rewards(&rt, rwd, TokenAmount::zero());

let expected = TokenAmount::from_atto(750_000);
let expected = TokenAmount::from_atto(750_000).add(rt.policy().new_miner_deposit.clone());
assert_eq!(expected, h.get_locked_funds(&rt));
}

#[test]
fn funds_vest() {
let h = ActorHarness::new(PERIOD_OFFSET);
let rt = h.new_runtime();
let mut rt = h.new_runtime();
rt.policy.new_miner_deposit = TokenAmount::zero();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's a problem that this test is touched at all, and that an unrealistic value is used for the deposit. Can you explain why (in code comments) ?

Copy link
Contributor Author

@hunjixin hunjixin Oct 10, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just too much test to fix, this is a quick fix

rt.set_balance(BIG_BALANCE.clone());
h.construct_and_verify(&rt);
let st = h.get_state(&rt);
Expand Down Expand Up @@ -79,10 +79,6 @@ fn funds_vest() {
let st = h.get_state(&rt);
let (locked_amt, _) = locked_reward_from_reward(amt);
assert_eq!(locked_amt, st.locked_funds);
// technically applying rewards without first activating cron is an impossible state but convenient for testing
let (_, acc) = check_state_invariants(rt.policy(), &st, rt.store(), &rt.get_balance());
assert_eq!(1, acc.len());
assert!(acc.messages().first().unwrap().contains("DeadlineCronActive == false"));
}

#[test]
Expand All @@ -99,18 +95,14 @@ fn penalty_is_burnt() {

let (mut expected_lock_amt, _) = locked_reward_from_reward(rwd);
expected_lock_amt -= penalty;
assert_eq!(expected_lock_amt, h.get_locked_funds(&rt));
// technically applying rewards without first activating cron is an impossible state but convenient for testing
let (_, acc) =
check_state_invariants(rt.policy(), &h.get_state(&rt), rt.store(), &rt.get_balance());
assert_eq!(1, acc.len());
assert!(acc.messages().first().unwrap().contains("DeadlineCronActive == false"));
assert_eq!(expected_lock_amt.add(rt.policy.new_miner_deposit.clone()), h.get_locked_funds(&rt));
}

#[test]
fn penalty_is_partially_burnt_and_stored_as_fee_debt() {
let h = ActorHarness::new(PERIOD_OFFSET);
let rt = h.new_runtime();
let mut rt = h.new_runtime();
rt.policy.new_miner_deposit = TokenAmount::zero();
rt.set_balance(BIG_BALANCE.clone());
h.construct_and_verify(&rt);
let st = h.get_state(&rt);
Expand Down Expand Up @@ -164,7 +156,7 @@ fn rewards_pay_back_fee_debt() {
h.construct_and_verify(&rt);
let mut st = h.get_state(&rt);

assert!(st.locked_funds.is_zero());
assert_eq!(rt.policy().new_miner_deposit, st.locked_funds);

let amt = rt.get_balance();
let available_before = h.get_available_balance(&rt).unwrap();
Expand Down Expand Up @@ -223,9 +215,5 @@ fn rewards_pay_back_fee_debt() {
assert_eq!(available_before + reward - init_fee_debt - &remaining_locked, available_balance);
assert!(!st.fee_debt.is_positive());
// remaining funds locked in vesting table
assert_eq!(remaining_locked, st.locked_funds);
// technically applying rewards without first activating cron is an impossible state but convenient for testing
let (_, acc) = check_state_invariants(rt.policy(), &st, rt.store(), &rt.get_balance());
assert_eq!(1, acc.len());
assert!(acc.messages().first().unwrap().contains("DeadlineCronActive == false"));
assert_eq!(remaining_locked.add(rt.policy.new_miner_deposit), st.locked_funds);
}
6 changes: 4 additions & 2 deletions actors/miner/tests/batch_method_network_fees_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,8 @@ fn insufficient_funds_for_batch_precommit_in_combination_of_fee_debt_and_network
#[test]
fn enough_funds_for_fee_debt_and_network_fee_but_not_for_pcd() {
let actor = ActorHarness::new(*PERIOD_OFFSET);
let rt = actor.new_runtime();
let mut rt = actor.new_runtime();
rt.policy.new_miner_deposit = TokenAmount::default();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why setting this unrealistic amount? Tests need to be updated to use a real deposit.

Also default is a rather opaque way of saying zero. Please use zero() everywhere so it's more obvious that this is not a default value, but a fake one.

rt.set_balance(BIG_BALANCE.clone());
let precommit_epoch = *PERIOD_OFFSET + 1;
rt.set_epoch(precommit_epoch);
Expand Down Expand Up @@ -230,7 +231,8 @@ fn enough_funds_for_fee_debt_and_network_fee_but_not_for_pcd() {
#[test]
fn enough_funds_for_everything() {
let actor = ActorHarness::new(*PERIOD_OFFSET);
let rt = actor.new_runtime();
let mut rt = actor.new_runtime();
rt.policy.new_miner_deposit = TokenAmount::default();
rt.set_balance(BIG_BALANCE.clone());
let precommit_epoch = *PERIOD_OFFSET + 1;
rt.set_epoch(precommit_epoch);
Expand Down
3 changes: 2 additions & 1 deletion actors/miner/tests/change_beneficiary_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ fn setup() -> (ActorHarness, MockRuntime) {
let period_offset = 100;

let h = ActorHarness::new(period_offset);
let rt = h.new_runtime();
let mut rt = h.new_runtime();
rt.policy.new_miner_deposit = TokenAmount::default();
h.construct_and_verify(&rt);
rt.balance.replace(TokenAmount::from_atto(big_balance));

Expand Down
3 changes: 2 additions & 1 deletion actors/miner/tests/change_owner_address_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ fn setup() -> (ActorHarness, MockRuntime) {
let period_offset = 100;

let h = ActorHarness::new(period_offset);
let rt = h.new_runtime();
let mut rt = h.new_runtime();
rt.policy.new_miner_deposit = TokenAmount::default();
h.construct_and_verify(&rt);
rt.balance.replace(BIG_BALANCE.clone());

Expand Down
4 changes: 3 additions & 1 deletion actors/miner/tests/change_peer_id_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use fil_actors_runtime::test_utils::{
expect_abort_contains_message, MockRuntime, EVM_ACTOR_CODE_ID,
};
use fvm_ipld_encoding::ipld_block::IpldBlock;
use fvm_shared::econ::TokenAmount;
use fvm_shared::error::ExitCode;

mod util;
Expand All @@ -14,7 +15,8 @@ fn setup() -> (ActorHarness, MockRuntime) {
let precommit_epoch = 1;

let h = ActorHarness::new(period_offset);
let rt = h.new_runtime();
let mut rt = h.new_runtime();
rt.policy.new_miner_deposit = TokenAmount::default();
h.construct_and_verify(&rt);
rt.balance.replace(BIG_BALANCE.clone());
rt.set_epoch(precommit_epoch);
Expand Down
4 changes: 3 additions & 1 deletion actors/miner/tests/change_worker_address_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ fn setup() -> (ActorHarness, MockRuntime) {
let period_offset = 100;

let h = ActorHarness::new(period_offset);
let rt = h.new_runtime();
let mut rt = h.new_runtime();
rt.policy.new_miner_deposit = TokenAmount::default();

h.construct_and_verify(&rt);
rt.balance.replace(BIG_BALANCE.clone());

Expand Down
5 changes: 4 additions & 1 deletion actors/miner/tests/check_sector_proven_test.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use fil_actors_runtime::test_utils::{expect_abort, MockRuntime};
use fvm_shared::econ::TokenAmount;
use fvm_shared::error::ExitCode;

mod util;
Expand All @@ -8,7 +9,9 @@ fn setup() -> (ActorHarness, MockRuntime) {
let period_offset = 100;

let h = ActorHarness::new(period_offset);
let rt = h.new_runtime();
let mut rt = h.new_runtime();
rt.policy.new_miner_deposit = TokenAmount::default();

h.construct_and_verify(&rt);
rt.balance.replace(BIG_BALANCE.clone());

Expand Down
3 changes: 2 additions & 1 deletion actors/miner/tests/compact_partitions_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ const PERIOD_OFFSET: ChainEpoch = 100;

fn setup() -> (ActorHarness, MockRuntime) {
let h = ActorHarness::new(PERIOD_OFFSET);
let rt = h.new_runtime();
let mut rt = h.new_runtime();
rt.policy.new_miner_deposit = TokenAmount::default();
h.construct_and_verify(&rt);
rt.balance.replace(BIG_BALANCE.clone());

Expand Down
5 changes: 4 additions & 1 deletion actors/miner/tests/compact_sector_numbers_tests.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use fil_actors_runtime::test_utils::{expect_abort, MockRuntime};
use fvm_shared::address::Address;
use fvm_shared::econ::TokenAmount;
use fvm_shared::sector::MAX_SECTOR_NUMBER;
use fvm_shared::{clock::ChainEpoch, error::ExitCode};

Expand All @@ -10,7 +11,9 @@ const PERIOD_OFFSET: ChainEpoch = 100;

fn setup() -> (ActorHarness, MockRuntime) {
let h = ActorHarness::new(PERIOD_OFFSET);
let rt = h.new_runtime();
let mut rt = h.new_runtime();
rt.policy.new_miner_deposit = TokenAmount::default();

h.construct_and_verify(&rt);
rt.balance.replace(BIG_BALANCE.clone());

Expand Down
5 changes: 4 additions & 1 deletion actors/miner/tests/confirm_update_worker_key_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use fil_actors_runtime::{
test_utils::MockRuntime,
};
use fvm_shared::address::Address;
use fvm_shared::econ::TokenAmount;

mod util;
use util::*;
Expand All @@ -15,7 +16,9 @@ fn setup() -> (ActorHarness, MockRuntime) {
let current_epoch = 5;

let h = ActorHarness::new(period_offset);
let rt = h.new_runtime();
let mut rt = h.new_runtime();
rt.policy.new_miner_deposit = TokenAmount::default();

h.construct_and_verify(&rt);
rt.balance.replace(BIG_BALANCE.clone());
rt.set_epoch(current_epoch);
Expand Down
10 changes: 7 additions & 3 deletions actors/miner/tests/deadline_cron_defers_stops_restarts.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use fvm_shared::clock::ChainEpoch;
use fvm_shared::econ::TokenAmount;

mod util;
use util::*;
Expand Down Expand Up @@ -34,7 +35,8 @@ fn cron_enrolls_on_precommit_prove_commits_and_continues_enrolling() {
#[test]
fn cron_enrolls_on_precommit_expires_on_pcd_expiration_re_enrolls_on_new_precommit_immediately() {
let h = ActorHarness::new(PERIOD_OFFSET);
let rt = h.new_runtime();
let mut rt = h.new_runtime();
rt.policy.new_miner_deposit = TokenAmount::default();
rt.set_balance(BIG_BALANCE.clone());
let epoch = PERIOD_OFFSET + 1;
rt.set_epoch(epoch);
Expand All @@ -49,7 +51,8 @@ fn cron_enrolls_on_precommit_expires_on_pcd_expiration_re_enrolls_on_new_precomm
fn cron_enrolls_on_precommit_expires_on_pcd_expiration_re_enrolls_on_new_precommit_after_falling_out_of_date(
) {
let h = ActorHarness::new(PERIOD_OFFSET);
let rt = h.new_runtime();
let mut rt = h.new_runtime();
rt.policy.new_miner_deposit = TokenAmount::default();
rt.set_balance(BIG_BALANCE.clone());
let mut epoch = PERIOD_OFFSET + 1;
rt.set_epoch(epoch);
Expand All @@ -68,7 +71,8 @@ fn cron_enrolls_on_precommit_expires_on_pcd_expiration_re_enrolls_on_new_precomm
#[test]
fn enroll_pcd_expire_re_enroll_x_3() {
let h = ActorHarness::new(PERIOD_OFFSET);
let rt = h.new_runtime();
let mut rt = h.new_runtime();
rt.policy.new_miner_deposit = TokenAmount::default();
rt.set_balance(BIG_BALANCE.clone());
let mut epoch = PERIOD_OFFSET + 1;
rt.set_epoch(epoch);
Expand Down
3 changes: 2 additions & 1 deletion actors/miner/tests/declare_recoveries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,8 @@ fn recovery_fails_during_active_consensus_fault() {

fn setup() -> (ActorHarness, MockRuntime) {
let h = ActorHarness::new(PERIOD_OFFSET);
let rt = h.new_runtime();
let mut rt = h.new_runtime();
rt.policy.new_miner_deposit = TokenAmount::default();
h.construct_and_verify(&rt);
rt.set_balance(BIG_BALANCE.clone());

Expand Down
4 changes: 3 additions & 1 deletion actors/miner/tests/exported_getters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,9 @@ fn info_getters() {
#[test]
fn collateral_getters() {
let h = ActorHarness::new(PERIOD_OFFSET);
let rt = h.new_runtime();
let mut rt = h.new_runtime();
rt.policy.new_miner_deposit = TokenAmount::default();

rt.balance.replace(BIG_BALANCE.clone());

let precommit_epoch = PERIOD_OFFSET + 1;
Expand Down
6 changes: 4 additions & 2 deletions actors/miner/tests/miner_actor_test_commitment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,8 @@ mod miner_actor_test_commitment {

let mut h = ActorHarness::new(period_offset);
h.set_proof_type(RegisteredSealProof::StackedDRG64GiBV1);
let rt = h.new_runtime();
let mut rt = h.new_runtime();
rt.policy.new_miner_deposit = TokenAmount::default();

rt.set_balance(insufficient_balance);
rt.set_received(TokenAmount::zero());
Expand Down Expand Up @@ -169,7 +170,8 @@ mod miner_actor_test_commitment {
let period_offset = ChainEpoch::from(100);

let mut h = ActorHarness::new(period_offset);
let rt = h.new_runtime();
let mut rt = h.new_runtime();
rt.policy.new_miner_deposit = TokenAmount::default();

rt.set_balance(BIG_BALANCE.clone());
rt.set_received(TokenAmount::zero());
Expand Down
Loading