Skip to content

Commit 56c32ff

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 04cbd8a commit 56c32ff

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,
@@ -4937,11 +4960,11 @@ impl ActorCode for Actor {
49374960
let res = Self::control_addresses(rt)?;
49384961
Ok(RawBytes::serialize(&res)?)
49394962
}
4940-
Some(Method::ChangeWorkerAddress) => {
4963+
Some(Method::ChangeWorkerAddress) | Some(Method::ChangeWorkerAddressExported) => {
49414964
Self::change_worker_address(rt, cbor::deserialize_params(params)?)?;
49424965
Ok(RawBytes::default())
49434966
}
4944-
Some(Method::ChangePeerID) => {
4967+
Some(Method::ChangePeerID) | Some(Method::ChangePeerIDExported) => {
49454968
Self::change_peer_id(rt, cbor::deserialize_params(params)?)?;
49464969
Ok(RawBytes::default())
49474970
}
@@ -4989,15 +5012,15 @@ impl ActorCode for Actor {
49895012
Self::report_consensus_fault(rt, cbor::deserialize_params(params)?)?;
49905013
Ok(RawBytes::default())
49915014
}
4992-
Some(Method::WithdrawBalance) => {
5015+
Some(Method::WithdrawBalance) | Some(Method::WithdrawBalanceExported) => {
49935016
let res = Self::withdraw_balance(rt, cbor::deserialize_params(params)?)?;
49945017
Ok(RawBytes::serialize(&res)?)
49955018
}
49965019
Some(Method::ConfirmSectorProofsValid) => {
49975020
Self::confirm_sector_proofs_valid(rt, cbor::deserialize_params(params)?)?;
49985021
Ok(RawBytes::default())
49995022
}
5000-
Some(Method::ChangeMultiaddrs) => {
5023+
Some(Method::ChangeMultiaddrs) | Some(Method::ChangeMultiaddrsExported) => {
50015024
Self::change_multiaddresses(rt, cbor::deserialize_params(params)?)?;
50025025
Ok(RawBytes::default())
50035026
}
@@ -5009,15 +5032,16 @@ impl ActorCode for Actor {
50095032
Self::compact_sector_numbers(rt, cbor::deserialize_params(params)?)?;
50105033
Ok(RawBytes::default())
50115034
}
5012-
Some(Method::ConfirmUpdateWorkerKey) => {
5013-
Self::confirm_update_worker_key(rt)?;
5035+
Some(Method::ConfirmChangeWorkerAddress)
5036+
| Some(Method::ConfirmChangeWorkerAddressExported) => {
5037+
Self::confirm_change_worker_address(rt)?;
50145038
Ok(RawBytes::default())
50155039
}
5016-
Some(Method::RepayDebt) => {
5040+
Some(Method::RepayDebt) | Some(Method::RepayDebtExported) => {
50175041
Self::repay_debt(rt)?;
50185042
Ok(RawBytes::default())
50195043
}
5020-
Some(Method::ChangeOwnerAddress) => {
5044+
Some(Method::ChangeOwnerAddress) | Some(Method::ChangeOwnerAddressExported) => {
50215045
Self::change_owner_address(rt, cbor::deserialize_params(params)?)?;
50225046
Ok(RawBytes::default())
50235047
}
@@ -5078,6 +5102,14 @@ impl ActorCode for Actor {
50785102
let res = Self::get_vesting_funds(rt)?;
50795103
Ok(RawBytes::serialize(res)?)
50805104
}
5105+
Some(Method::GetPeerIDExported) => {
5106+
let res = Self::get_peer_id(rt)?;
5107+
Ok(RawBytes::serialize(res)?)
5108+
}
5109+
Some(Method::GetMultiaddrsExported) => {
5110+
let res = Self::get_multiaddresses(rt)?;
5111+
Ok(RawBytes::serialize(res)?)
5112+
}
50815113
}
50825114
}
50835115
}

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)