Skip to content

Commit 325a499

Browse files
arajasekanorth
andcommitted
Power actor: Export methods to CreateMiner and get miner counts (#868)
* Power: Export CreateMiner * Power Actor: Export MinerCount and MinerConsensusCount * Update actors/power/src/lib.rs Co-authored-by: Alex <[email protected]> Co-authored-by: Alex <[email protected]>
1 parent 117a539 commit 325a499

File tree

4 files changed

+140
-14
lines changed

4 files changed

+140
-14
lines changed

actors/power/src/lib.rs

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,11 @@ pub enum Method {
6262
SubmitPoRepForBulkVerify = 8,
6363
CurrentTotalPower = 9,
6464
// Method numbers derived from FRC-0042 standards
65+
CreateMinerExported = frc42_dispatch::method_hash!("CreateMiner"),
6566
NetworkRawPowerExported = frc42_dispatch::method_hash!("NetworkRawPower"),
6667
MinerRawPowerExported = frc42_dispatch::method_hash!("MinerRawPower"),
68+
MinerCountExported = frc42_dispatch::method_hash!("MinerCount"),
69+
MinerConsensusCountExported = frc42_dispatch::method_hash!("MinerConsensusCount"),
6770
}
6871

6972
pub const ERR_TOO_MANY_PROVE_COMMITS: ExitCode = ExitCode::new(32);
@@ -396,6 +399,26 @@ impl Actor {
396399
Ok(MinerRawPowerReturn { raw_byte_power, meets_consensus_minimum })
397400
}
398401

402+
/// Returns the total number of miners created, regardless of whether or not
403+
/// they have any pledged storage.
404+
fn miner_count(rt: &mut impl Runtime) -> Result<MinerCountReturn, ActorError> {
405+
rt.validate_immediate_caller_accept_any()?;
406+
let st: State = rt.state()?;
407+
408+
Ok(MinerCountReturn { miner_count: st.miner_count })
409+
}
410+
411+
/// Returns the total number of miners that have more than the consensus minimum amount of storage active.
412+
/// Active means that the storage must not be faulty.
413+
fn miner_consensus_count(
414+
rt: &mut impl Runtime,
415+
) -> Result<MinerConsensusCountReturn, ActorError> {
416+
rt.validate_immediate_caller_accept_any()?;
417+
let st: State = rt.state()?;
418+
419+
Ok(MinerConsensusCountReturn { miner_consensus_count: st.miner_above_min_power_count })
420+
}
421+
399422
fn process_batch_proof_verifies(
400423
rt: &mut impl Runtime,
401424
rewret: &ThisEpochRewardReturn,
@@ -663,7 +686,7 @@ impl ActorCode for Actor {
663686
Self::constructor(rt)?;
664687
Ok(RawBytes::default())
665688
}
666-
Some(Method::CreateMiner) => {
689+
Some(Method::CreateMiner) | Some(Method::CreateMinerExported) => {
667690
let res = Self::create_miner(rt, cbor::deserialize_params(params)?)?;
668691
Ok(RawBytes::serialize(res)?)
669692
}
@@ -700,6 +723,14 @@ impl ActorCode for Actor {
700723
let res = Self::miner_raw_power(rt, cbor::deserialize_params(params)?)?;
701724
Ok(RawBytes::serialize(res)?)
702725
}
726+
Some(Method::MinerCountExported) => {
727+
let res = Self::miner_count(rt)?;
728+
Ok(RawBytes::serialize(res)?)
729+
}
730+
Some(Method::MinerConsensusCountExported) => {
731+
let res = Self::miner_consensus_count(rt)?;
732+
Ok(RawBytes::serialize(res)?)
733+
}
703734
None => Err(actor_error!(unhandled_message; "Invalid method")),
704735
}
705736
}

actors/power/src/types.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,3 +93,15 @@ pub struct MinerRawPowerReturn {
9393
}
9494

9595
impl Cbor for MinerRawPowerReturn {}
96+
97+
#[derive(Serialize_tuple, Deserialize_tuple, Debug, Clone, Eq, PartialEq)]
98+
#[serde(transparent)]
99+
pub struct MinerCountReturn {
100+
pub miner_count: i64,
101+
}
102+
103+
#[derive(Serialize_tuple, Deserialize_tuple, Debug, Clone, Eq, PartialEq)]
104+
#[serde(transparent)]
105+
pub struct MinerConsensusCountReturn {
106+
pub miner_consensus_count: i64,
107+
}

actors/power/tests/harness/mod.rs

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
use cid::Cid;
22
use fil_actor_power::detail::GAS_ON_SUBMIT_VERIFY_SEAL;
3-
use fil_actor_power::epoch_key;
43
use fil_actor_power::ext::miner::ConfirmSectorProofsParams;
54
use fil_actor_power::ext::miner::CONFIRM_SECTOR_PROOFS_VALID_METHOD;
65
use fil_actor_power::ext::reward::Method::ThisEpochReward;
76
use fil_actor_power::ext::reward::UPDATE_NETWORK_KPI;
87
use fil_actor_power::testing::check_state_invariants;
9-
use fil_actor_power::CronEvent;
108
use fil_actor_power::EnrollCronEventParams;
119
use fil_actor_power::CRON_QUEUE_AMT_BITWIDTH;
1210
use fil_actor_power::CRON_QUEUE_HAMT_BITWIDTH;
11+
use fil_actor_power::{epoch_key, MinerCountReturn};
12+
use fil_actor_power::{CronEvent, MinerConsensusCountReturn};
1313
use fil_actors_runtime::runtime::RuntimePolicy;
1414
use fil_actors_runtime::test_utils::CRON_ACTOR_CODE_ID;
1515
use fil_actors_runtime::Multimap;
@@ -210,9 +210,15 @@ impl Harness {
210210
keys.iter().map(|k| Address::from_bytes(k).unwrap()).collect::<Vec<_>>()
211211
}
212212

213-
pub fn miner_count(&self, rt: &MockRuntime) -> i64 {
214-
let st: State = rt.get_state();
215-
st.miner_count
213+
pub fn miner_count(&self, rt: &mut MockRuntime) -> i64 {
214+
rt.expect_validate_caller_any();
215+
let ret: MinerCountReturn = rt
216+
.call::<PowerActor>(Method::MinerCountExported as MethodNum, &RawBytes::default())
217+
.unwrap()
218+
.deserialize()
219+
.unwrap();
220+
221+
ret.miner_count
216222
}
217223

218224
pub fn this_epoch_baseline_power(&self) -> &StoragePower {
@@ -366,8 +372,17 @@ impl Harness {
366372
}
367373

368374
pub fn expect_miners_above_min_power(&self, rt: &mut MockRuntime, count: i64) {
369-
let st: State = rt.get_state();
370-
assert_eq!(count, st.miner_above_min_power_count);
375+
rt.expect_validate_caller_any();
376+
let ret: MinerConsensusCountReturn = rt
377+
.call::<PowerActor>(
378+
Method::MinerConsensusCountExported as MethodNum,
379+
&RawBytes::default(),
380+
)
381+
.unwrap()
382+
.deserialize()
383+
.unwrap();
384+
385+
assert_eq!(count, ret.miner_consensus_count);
371386
}
372387

373388
pub fn expect_query_network_info(&self, rt: &mut MockRuntime) {

actors/power/tests/power_actor_tests.rs

Lines changed: 74 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,12 @@ use fvm_shared::clock::ChainEpoch;
1313
use fvm_shared::econ::TokenAmount;
1414
use fvm_shared::error::ExitCode;
1515
use fvm_shared::sector::{RegisteredPoStProof, StoragePower};
16+
use fvm_shared::MethodNum;
1617
use num_traits::Zero;
1718
use std::ops::Neg;
1819

1920
use fil_actor_power::{
20-
consensus_miner_min_power, Actor as PowerActor, Actor, CreateMinerParams,
21+
consensus_miner_min_power, Actor as PowerActor, Actor, CreateMinerParams, CreateMinerReturn,
2122
EnrollCronEventParams, Method, MinerRawPowerParams, MinerRawPowerReturn, NetworkRawPowerReturn,
2223
State, UpdateClaimedPowerParams, CONSENSUS_MINER_MIN_MINERS,
2324
};
@@ -326,8 +327,7 @@ fn new_miner_updates_miner_above_min_power_count() {
326327
h.window_post_proof = test.proof;
327328
h.create_miner_basic(&mut rt, *OWNER, *OWNER, MINER1).unwrap();
328329

329-
let st: State = rt.get_state();
330-
assert_eq!(test.expected_miners, st.miner_above_min_power_count);
330+
h.expect_miners_above_min_power(&mut rt, test.expected_miners);
331331
h.check_state(&rt);
332332
}
333333
}
@@ -372,8 +372,7 @@ fn power_accounting_crossing_threshold() {
372372
let expected_total_above = &(power_unit * 4);
373373
h.expect_total_power_eager(&mut rt, expected_total_above, &(expected_total_above * 10));
374374

375-
let st: State = rt.get_state();
376-
assert_eq!(4, st.miner_above_min_power_count);
375+
h.expect_miners_above_min_power(&mut rt, 4);
377376

378377
// Less than 4 miners above threshold again small miner power is counted again
379378
h.update_claimed_power(&mut rt, MINER4, &delta.neg(), &(delta.neg() * 10));
@@ -1011,7 +1010,7 @@ mod cron_tests {
10111010
assert!(h.get_claim(&rt, &miner1).is_none());
10121011

10131012
// miner count has been reduced to 1
1014-
assert_eq!(h.miner_count(&rt), 1);
1013+
assert_eq!(h.miner_count(&mut rt), 1);
10151014

10161015
// next epoch, only the reward actor is invoked
10171016
rt.set_epoch(3);
@@ -1441,3 +1440,72 @@ mod submit_porep_for_bulk_verify_tests {
14411440
h.check_state(&rt);
14421441
}
14431442
}
1443+
1444+
#[test]
1445+
fn create_miner_restricted_correctly() {
1446+
let (h, mut rt) = setup();
1447+
1448+
let peer = "miner".as_bytes().to_vec();
1449+
let multiaddrs = vec![BytesDe("multiaddr".as_bytes().to_vec())];
1450+
1451+
let params = serialize(
1452+
&CreateMinerParams {
1453+
owner: *OWNER,
1454+
worker: *OWNER,
1455+
window_post_proof_type: RegisteredPoStProof::StackedDRGWinning2KiBV1,
1456+
peer: peer.clone(),
1457+
multiaddrs: multiaddrs.clone(),
1458+
},
1459+
"create miner params",
1460+
)
1461+
.unwrap();
1462+
1463+
rt.set_caller(make_identity_cid(b"1234"), *OWNER);
1464+
1465+
// cannot call the unexported method
1466+
expect_abort_contains_message(
1467+
ExitCode::USR_FORBIDDEN,
1468+
"must be built-in",
1469+
rt.call::<PowerActor>(Method::CreateMiner as MethodNum, &params),
1470+
);
1471+
1472+
// can call the exported method
1473+
1474+
rt.expect_validate_caller_any();
1475+
let expected_init_params = ExecParams {
1476+
code_cid: *MINER_ACTOR_CODE_ID,
1477+
constructor_params: serialize(
1478+
&MinerConstructorParams {
1479+
owner: *OWNER,
1480+
worker: *OWNER,
1481+
control_addresses: vec![],
1482+
window_post_proof_type: RegisteredPoStProof::StackedDRGWinning2KiBV1,
1483+
peer_id: peer,
1484+
multi_addresses: multiaddrs,
1485+
},
1486+
"minerctor params",
1487+
)
1488+
.unwrap(),
1489+
};
1490+
let create_miner_ret = CreateMinerReturn { id_address: *MINER, robust_address: *ACTOR };
1491+
rt.expect_send(
1492+
INIT_ACTOR_ADDR,
1493+
EXEC_METHOD,
1494+
RawBytes::serialize(expected_init_params).unwrap(),
1495+
TokenAmount::zero(),
1496+
RawBytes::serialize(create_miner_ret).unwrap(),
1497+
ExitCode::OK,
1498+
);
1499+
1500+
let ret: CreateMinerReturn = rt
1501+
.call::<PowerActor>(Method::CreateMinerExported as MethodNum, &params)
1502+
.unwrap()
1503+
.deserialize()
1504+
.unwrap();
1505+
rt.verify();
1506+
1507+
assert_eq!(ret.id_address, *MINER);
1508+
assert_eq!(ret.robust_address, *ACTOR);
1509+
1510+
h.check_state(&rt);
1511+
}

0 commit comments

Comments
 (0)