Skip to content

Commit b0b688d

Browse files
committed
Miner: Export several more methods (#863)
* Miner: Export ChangeWorkerAddress * Miner: Export ChangePeerID * Miner: Export WithdrawBalance * Miner: Export ChangeMultiaddrs * Miner: Export ConfirmUpdateWorkerKey * Miner: Export RepayDebt * Miner: Export ChangeOwnerAddress * Miner: Add exported getters for PeerID & multiaddrs * Miner: Refactor: Rename ConfirmUpdateWorkerKey to ConfirmChangeWorkerAddress
1 parent 4bb5e5e commit b0b688d

10 files changed

+409
-41
lines changed

actors/miner/src/lib.rs

Lines changed: 42 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ pub enum Method {
112112
ChangeMultiaddrs = 18,
113113
CompactPartitions = 19,
114114
CompactSectorNumbers = 20,
115-
ConfirmUpdateWorkerKey = 21,
115+
ConfirmChangeWorkerAddress = 21,
116116
RepayDebt = 22,
117117
ChangeOwnerAddress = 23,
118118
DisputeWindowedPoSt = 24,
@@ -125,13 +125,22 @@ pub enum Method {
125125
GetBeneficiary = 31,
126126
ExtendSectorExpiration2 = 32,
127127
// Method numbers derived from FRC-0042 standards
128+
ChangeWorkerAddressExported = frc42_dispatch::method_hash!("ChangeWorkerAddress"),
129+
ChangePeerIDExported = frc42_dispatch::method_hash!("ChangePeerID"),
130+
WithdrawBalanceExported = frc42_dispatch::method_hash!("WithdrawBalance"),
131+
ChangeMultiaddrsExported = frc42_dispatch::method_hash!("ChangeMultiaddrs"),
132+
ConfirmChangeWorkerAddressExported = frc42_dispatch::method_hash!("ConfirmChangeWorkerAddress"),
133+
RepayDebtExported = frc42_dispatch::method_hash!("RepayDebt"),
134+
ChangeOwnerAddressExported = frc42_dispatch::method_hash!("ChangeOwnerAddress"),
128135
ChangeBenificiaryExported = frc42_dispatch::method_hash!("ChangeBeneficiary"),
129136
GetBeneficiaryExported = frc42_dispatch::method_hash!("GetBeneficiary"),
130137
GetOwnerExported = frc42_dispatch::method_hash!("GetOwner"),
131138
IsControllingAddressExported = frc42_dispatch::method_hash!("IsControllingAddress"),
132139
GetSectorSizeExported = frc42_dispatch::method_hash!("GetSectorSize"),
133140
GetAvailableBalanceExported = frc42_dispatch::method_hash!("GetAvailableBalance"),
134141
GetVestingFundsExported = frc42_dispatch::method_hash!("GetVestingFunds"),
142+
GetPeerIDExported = frc42_dispatch::method_hash!("GetPeerID"),
143+
GetMultiaddrsExported = frc42_dispatch::method_hash!("GetMultiaddrs"),
135144
}
136145

137146
pub const ERR_BALANCE_INVARIANTS_BROKEN: ExitCode = ExitCode::new(1000);
@@ -344,7 +353,7 @@ impl Actor {
344353
}
345354

346355
/// Triggers a worker address change if a change has been requested and its effective epoch has arrived.
347-
fn confirm_update_worker_key(rt: &mut impl Runtime) -> Result<(), ActorError> {
356+
fn confirm_change_worker_address(rt: &mut impl Runtime) -> Result<(), ActorError> {
348357
rt.transaction(|state: &mut State, rt| {
349358
let mut info = get_miner_info(rt.store(), state)?;
350359

@@ -413,6 +422,13 @@ impl Actor {
413422
})
414423
}
415424

425+
fn get_peer_id(rt: &mut impl Runtime) -> Result<GetPeerIDReturn, ActorError> {
426+
rt.validate_immediate_caller_accept_any()?;
427+
let state: State = rt.state()?;
428+
let peer_id = get_miner_info(rt.store(), &state)?.peer_id;
429+
Ok(GetPeerIDReturn { peer_id })
430+
}
431+
416432
fn change_peer_id(rt: &mut impl Runtime, params: ChangePeerIDParams) -> Result<(), ActorError> {
417433
let policy = rt.policy();
418434
check_peer_info(policy, &params.new_id, &[])?;
@@ -434,6 +450,13 @@ impl Actor {
434450
Ok(())
435451
}
436452

453+
fn get_multiaddresses(rt: &mut impl Runtime) -> Result<GetMultiaddrsReturn, ActorError> {
454+
rt.validate_immediate_caller_accept_any()?;
455+
let state: State = rt.state()?;
456+
let multi_addrs = get_miner_info(rt.store(), &state)?.multi_address;
457+
Ok(GetMultiaddrsReturn { multi_addrs })
458+
}
459+
437460
fn change_multiaddresses(
438461
rt: &mut impl Runtime,
439462
params: ChangeMultiaddrsParams,
@@ -4936,11 +4959,11 @@ impl ActorCode for Actor {
49364959
let res = Self::control_addresses(rt)?;
49374960
Ok(RawBytes::serialize(&res)?)
49384961
}
4939-
Some(Method::ChangeWorkerAddress) => {
4962+
Some(Method::ChangeWorkerAddress) | Some(Method::ChangeWorkerAddressExported) => {
49404963
Self::change_worker_address(rt, cbor::deserialize_params(params)?)?;
49414964
Ok(RawBytes::default())
49424965
}
4943-
Some(Method::ChangePeerID) => {
4966+
Some(Method::ChangePeerID) | Some(Method::ChangePeerIDExported) => {
49444967
Self::change_peer_id(rt, cbor::deserialize_params(params)?)?;
49454968
Ok(RawBytes::default())
49464969
}
@@ -4988,15 +5011,15 @@ impl ActorCode for Actor {
49885011
Self::report_consensus_fault(rt, cbor::deserialize_params(params)?)?;
49895012
Ok(RawBytes::default())
49905013
}
4991-
Some(Method::WithdrawBalance) => {
5014+
Some(Method::WithdrawBalance) | Some(Method::WithdrawBalanceExported) => {
49925015
let res = Self::withdraw_balance(rt, cbor::deserialize_params(params)?)?;
49935016
Ok(RawBytes::serialize(&res)?)
49945017
}
49955018
Some(Method::ConfirmSectorProofsValid) => {
49965019
Self::confirm_sector_proofs_valid(rt, cbor::deserialize_params(params)?)?;
49975020
Ok(RawBytes::default())
49985021
}
4999-
Some(Method::ChangeMultiaddrs) => {
5022+
Some(Method::ChangeMultiaddrs) | Some(Method::ChangeMultiaddrsExported) => {
50005023
Self::change_multiaddresses(rt, cbor::deserialize_params(params)?)?;
50015024
Ok(RawBytes::default())
50025025
}
@@ -5008,15 +5031,16 @@ impl ActorCode for Actor {
50085031
Self::compact_sector_numbers(rt, cbor::deserialize_params(params)?)?;
50095032
Ok(RawBytes::default())
50105033
}
5011-
Some(Method::ConfirmUpdateWorkerKey) => {
5012-
Self::confirm_update_worker_key(rt)?;
5034+
Some(Method::ConfirmChangeWorkerAddress)
5035+
| Some(Method::ConfirmChangeWorkerAddressExported) => {
5036+
Self::confirm_change_worker_address(rt)?;
50135037
Ok(RawBytes::default())
50145038
}
5015-
Some(Method::RepayDebt) => {
5039+
Some(Method::RepayDebt) | Some(Method::RepayDebtExported) => {
50165040
Self::repay_debt(rt)?;
50175041
Ok(RawBytes::default())
50185042
}
5019-
Some(Method::ChangeOwnerAddress) => {
5043+
Some(Method::ChangeOwnerAddress) | Some(Method::ChangeOwnerAddressExported) => {
50205044
Self::change_owner_address(rt, cbor::deserialize_params(params)?)?;
50215045
Ok(RawBytes::default())
50225046
}
@@ -5077,6 +5101,14 @@ impl ActorCode for Actor {
50775101
let res = Self::get_vesting_funds(rt)?;
50785102
Ok(RawBytes::serialize(res)?)
50795103
}
5104+
Some(Method::GetPeerIDExported) => {
5105+
let res = Self::get_peer_id(rt)?;
5106+
Ok(RawBytes::serialize(res)?)
5107+
}
5108+
Some(Method::GetMultiaddrsExported) => {
5109+
let res = Self::get_multiaddresses(rt)?;
5110+
Ok(RawBytes::serialize(res)?)
5111+
}
50805112
}
50815113
}
50825114
}

actors/miner/src/types.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -529,3 +529,14 @@ pub struct GetVestingFundsReturn {
529529
}
530530

531531
impl Cbor for GetVestingFundsReturn {}
532+
533+
#[derive(Debug, Default, PartialEq, Eq, Clone, Serialize_tuple, Deserialize_tuple)]
534+
pub struct GetPeerIDReturn {
535+
#[serde(with = "serde_bytes")]
536+
pub peer_id: Vec<u8>,
537+
}
538+
539+
#[derive(Debug, Default, PartialEq, Clone, Serialize_tuple, Deserialize_tuple)]
540+
pub struct GetMultiaddrsReturn {
541+
pub multi_addrs: Vec<BytesDe>,
542+
}

actors/miner/tests/change_owner_address_test.rs

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1+
use fil_actor_miner::{Actor, Method};
12
use fil_actors_runtime::test_utils::{
2-
expect_abort, new_bls_addr, MockRuntime, ACCOUNT_ACTOR_CODE_ID, MULTISIG_ACTOR_CODE_ID,
3+
expect_abort, expect_abort_contains_message, make_identity_cid, new_bls_addr, MockRuntime,
4+
ACCOUNT_ACTOR_CODE_ID, MULTISIG_ACTOR_CODE_ID,
35
};
6+
use fvm_ipld_encoding::RawBytes;
47
use fvm_shared::econ::TokenAmount;
58
use fvm_shared::{address::Address, error::ExitCode};
69

@@ -52,6 +55,47 @@ fn successful_change() {
5255
h.check_state(&rt);
5356
}
5457

58+
#[test]
59+
fn change_owner_address_restricted_correctly() {
60+
let (h, mut rt) = setup();
61+
62+
let params = &RawBytes::serialize(NEW_ADDRESS).unwrap();
63+
rt.set_caller(make_identity_cid(b"1234"), h.owner);
64+
65+
// fail to call the unexported method
66+
67+
expect_abort_contains_message(
68+
ExitCode::USR_FORBIDDEN,
69+
"must be built-in",
70+
rt.call::<Actor>(Method::ChangeOwnerAddress as u64, params),
71+
);
72+
73+
// can call the exported method
74+
75+
rt.expect_validate_caller_addr(vec![h.owner]);
76+
rt.call::<Actor>(Method::ChangeOwnerAddressExported as u64, params).unwrap();
77+
78+
rt.verify();
79+
80+
let info = h.get_info(&rt);
81+
assert_eq!(h.owner, info.owner);
82+
assert_eq!(NEW_ADDRESS, info.pending_owner_address.unwrap());
83+
84+
// new owner can also call the exported method
85+
86+
rt.expect_validate_caller_addr(vec![NEW_ADDRESS]);
87+
rt.set_caller(make_identity_cid(b"1234"), NEW_ADDRESS);
88+
rt.call::<Actor>(Method::ChangeOwnerAddressExported as u64, params).unwrap();
89+
90+
rt.verify();
91+
let info = h.get_info(&rt);
92+
assert_eq!(NEW_ADDRESS, info.owner);
93+
assert_eq!(NEW_ADDRESS, info.beneficiary);
94+
assert!(info.pending_owner_address.is_none());
95+
96+
h.check_state(&rt);
97+
}
98+
5599
#[test]
56100
fn successful_keep_beneficiary_when_change_owner() {
57101
let (mut h, mut rt) = setup();

actors/miner/tests/change_peer_id_test.rs

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
use fil_actors_runtime::test_utils::MockRuntime;
1+
use fil_actor_miner::{Actor, ChangePeerIDParams, GetPeerIDReturn, Method};
2+
use fil_actors_runtime::test_utils::{
3+
expect_abort_contains_message, make_identity_cid, MockRuntime,
4+
};
5+
use fvm_ipld_encoding::RawBytes;
6+
use fvm_shared::error::ExitCode;
27

38
mod util;
49
use util::*;
@@ -24,3 +29,42 @@ fn successfully_change_peer_id() {
2429

2530
h.check_state(&rt);
2631
}
32+
33+
#[test]
34+
fn change_peer_id_restricted_correctly() {
35+
let (h, mut rt) = setup();
36+
37+
let new_id = b"cthulhu".to_vec();
38+
39+
let params = RawBytes::serialize(ChangePeerIDParams { new_id: new_id.clone() }).unwrap();
40+
41+
rt.set_caller(make_identity_cid(b"1234"), h.worker);
42+
43+
// fail to call the unexported setter
44+
45+
expect_abort_contains_message(
46+
ExitCode::USR_FORBIDDEN,
47+
"must be built-in",
48+
rt.call::<Actor>(Method::ChangePeerID as u64, &params),
49+
);
50+
51+
// call the exported setter
52+
53+
rt.expect_validate_caller_addr(h.caller_addrs());
54+
55+
rt.call::<Actor>(Method::ChangePeerIDExported as u64, &params).unwrap();
56+
57+
// call the exported getter
58+
59+
rt.expect_validate_caller_any();
60+
let ret: GetPeerIDReturn = rt
61+
.call::<Actor>(Method::GetPeerIDExported as u64, &RawBytes::default())
62+
.unwrap()
63+
.deserialize()
64+
.unwrap();
65+
rt.verify();
66+
67+
assert_eq!(new_id, ret.peer_id);
68+
69+
h.check_state(&rt);
70+
}

actors/miner/tests/change_worker_address_test.rs

Lines changed: 76 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use fvm_ipld_encoding::RawBytes;
1111
use fvm_shared::{address::Address, econ::TokenAmount, error::ExitCode};
1212

1313
mod util;
14+
use fil_actors_runtime::test_utils::make_identity_cid;
1415
use itertools::Itertools;
1516
use num_traits::Zero;
1617
use util::*;
@@ -50,7 +51,7 @@ fn successfully_change_only_the_worker_address() {
5051
rt.set_epoch(deadline.period_end());
5152
assert!(deadline.period_end() < effective_epoch);
5253

53-
h.confirm_update_worker_key(&mut rt).unwrap();
54+
h.confirm_change_worker_address(&mut rt).unwrap();
5455

5556
let info = h.get_info(&rt);
5657
assert_eq!(info.pending_worker_key.unwrap().new_worker, new_worker);
@@ -60,7 +61,7 @@ fn successfully_change_only_the_worker_address() {
6061
rt.set_epoch(effective_epoch);
6162

6263
// enact worker change
63-
h.confirm_update_worker_key(&mut rt).unwrap();
64+
h.confirm_change_worker_address(&mut rt).unwrap();
6465

6566
// assert address has changed
6667
let info = h.get_info(&rt);
@@ -73,6 +74,77 @@ fn successfully_change_only_the_worker_address() {
7374
h.check_state(&rt);
7475
}
7576

77+
#[test]
78+
fn change_and_confirm_worker_address_restricted_correctly() {
79+
let (h, mut rt) = setup();
80+
81+
let original_control_addresses = h.control_addrs.clone();
82+
let new_worker = Address::new_id(999);
83+
84+
rt.set_address_actor_type(new_worker, *ACCOUNT_ACTOR_CODE_ID);
85+
86+
let params = RawBytes::serialize(ChangeWorkerAddressParams {
87+
new_worker,
88+
new_control_addresses: original_control_addresses,
89+
})
90+
.unwrap();
91+
92+
rt.set_caller(make_identity_cid(b"1234"), h.owner);
93+
94+
// fail to call the unexported method
95+
96+
expect_abort_contains_message(
97+
ExitCode::USR_FORBIDDEN,
98+
"must be built-in",
99+
rt.call::<Actor>(Method::ChangeWorkerAddress as u64, &params),
100+
);
101+
102+
// call the exported method
103+
rt.expect_send(
104+
new_worker,
105+
AccountMethod::PubkeyAddress as u64,
106+
RawBytes::default(),
107+
TokenAmount::zero(),
108+
RawBytes::serialize(h.worker_key).unwrap(),
109+
ExitCode::OK,
110+
);
111+
112+
rt.expect_validate_caller_addr(vec![h.owner]);
113+
114+
rt.call::<Actor>(Method::ChangeWorkerAddressExported as u64, &params).unwrap();
115+
116+
rt.verify();
117+
118+
// assert change has been made in state
119+
let pending_worker_key = h.get_info(&rt).pending_worker_key.unwrap();
120+
assert_eq!(pending_worker_key.new_worker, new_worker);
121+
122+
// confirmation time
123+
124+
// move to deadline containing effective epoch
125+
rt.set_epoch(rt.epoch + rt.policy.worker_key_change_delay);
126+
127+
// fail to call the unexported method
128+
129+
expect_abort_contains_message(
130+
ExitCode::USR_FORBIDDEN,
131+
"must be built-in",
132+
rt.call::<Actor>(Method::ConfirmChangeWorkerAddress as u64, &RawBytes::default()),
133+
);
134+
135+
// call the exported method
136+
rt.expect_validate_caller_addr(vec![h.owner]);
137+
rt.call::<Actor>(Method::ConfirmChangeWorkerAddressExported as u64, &RawBytes::default())
138+
.unwrap();
139+
rt.verify();
140+
141+
// assert address has changed
142+
let info = h.get_info(&rt);
143+
assert_eq!(new_worker, info.worker);
144+
145+
h.check_state(&rt);
146+
}
147+
76148
#[test]
77149
fn change_cannot_be_overridden() {
78150
let (h, mut rt) = setup();
@@ -100,7 +172,7 @@ fn change_cannot_be_overridden() {
100172
assert_eq!(pending_worker_key.effective_at, effective_epoch);
101173

102174
rt.set_epoch(effective_epoch);
103-
h.confirm_update_worker_key(&mut rt).unwrap();
175+
h.confirm_change_worker_address(&mut rt).unwrap();
104176

105177
// assert original change is effected
106178
assert_eq!(new_worker_1, h.get_info(&rt).worker);
@@ -146,7 +218,7 @@ fn successfully_change_both_worker_and_control_addresses() {
146218

147219
// set current epoch and update worker key
148220
rt.set_epoch(effective_epoch);
149-
h.confirm_update_worker_key(&mut rt).unwrap();
221+
h.confirm_change_worker_address(&mut rt).unwrap();
150222

151223
// assert both worker and control addresses have changed
152224
let info = h.get_info(&rt);

0 commit comments

Comments
 (0)