Skip to content

Commit 9159281

Browse files
committed
Export stable methods for public access (#807)
* Export Datacap Actor methods * Export Init Actor methods * Export Market Actor methods * Export Miner Actor methods * Export Multisig Actor methods * Export Verifreg Actor methods * Address review
1 parent 32e7e4a commit 9159281

25 files changed

+445
-94
lines changed

Cargo.lock

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

actors/datacap/src/lib.rs

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ use num_traits::{FromPrimitive, Zero};
2020
use fil_actors_runtime::cbor::serialize;
2121
use fil_actors_runtime::runtime::{ActorCode, Runtime};
2222
use fil_actors_runtime::{
23-
actor_error, cbor, ActorContext, ActorError, AsActorError, SYSTEM_ACTOR_ADDR,
23+
actor_error, cbor, restrict_internal_api, ActorContext, ActorError, AsActorError,
24+
SYSTEM_ACTOR_ADDR,
2425
};
2526

2627
pub use self::state::State;
@@ -42,9 +43,10 @@ lazy_static! {
4243
* BigInt::from(1_000_000_000_000_000_000_000_i128)
4344
);
4445
}
45-
/// Static method numbers for builtin-actor private dispatch.
46-
/// The methods are also expected to be exposed via FRC-XXXX standard calling convention,
47-
/// with numbers determined by name.
46+
47+
/// Datacap actor methods available
48+
/// Some methods are available under 2 method nums -- a static number for "private" builtin actor usage,
49+
/// and via FRC-XXXX calling convention, with number determined by method name.
4850
#[derive(FromPrimitive)]
4951
#[repr(u64)]
5052
pub enum Method {
@@ -65,6 +67,19 @@ pub enum Method {
6567
Burn = 19,
6668
BurnFrom = 20,
6769
Allowance = 21,
70+
// Method numbers derived from FRC-XXXX standards
71+
NameExported = frc42_dispatch::method_hash!("Name"),
72+
SymbolExported = frc42_dispatch::method_hash!("Symbol"),
73+
TotalSupplyExported = frc42_dispatch::method_hash!("TotalSupply"),
74+
BalanceOfExported = frc42_dispatch::method_hash!("BalanceOf"),
75+
TransferExported = frc42_dispatch::method_hash!("Transfer"),
76+
TransferFromExported = frc42_dispatch::method_hash!("TransferFrom"),
77+
IncreaseAllowanceExported = frc42_dispatch::method_hash!("IncreaseAllowance"),
78+
DecreaseAllowanceExported = frc42_dispatch::method_hash!("DecreaseAllowance"),
79+
RevokeAllowanceExported = frc42_dispatch::method_hash!("RevokeAllowance"),
80+
BurnExported = frc42_dispatch::method_hash!("Burn"),
81+
BurnFromExported = frc42_dispatch::method_hash!("BurnFrom"),
82+
AllowanceExported = frc42_dispatch::method_hash!("Allowance"),
6883
}
6984

7085
pub struct Actor;
@@ -448,6 +463,7 @@ impl ActorCode for Actor {
448463
where
449464
RT: Runtime,
450465
{
466+
restrict_internal_api(rt, method)?;
451467
// I'm trying to find a fixed template for these blocks so we can macro it.
452468
// Current blockers:
453469
// - the serialize method maps () to CBOR null (we want no bytes instead)
@@ -465,51 +481,51 @@ impl ActorCode for Actor {
465481
let ret = Self::destroy(rt, cbor::deserialize_params(params)?)?;
466482
serialize(&ret, "destroy result")
467483
}
468-
Some(Method::Name) => {
484+
Some(Method::Name) | Some(Method::NameExported) => {
469485
let ret = Self::name(rt)?;
470486
serialize(&ret, "name result")
471487
}
472-
Some(Method::Symbol) => {
488+
Some(Method::Symbol) | Some(Method::SymbolExported) => {
473489
let ret = Self::symbol(rt)?;
474490
serialize(&ret, "symbol result")
475491
}
476-
Some(Method::TotalSupply) => {
492+
Some(Method::TotalSupply) | Some(Method::TotalSupplyExported) => {
477493
let ret = Self::total_supply(rt, cbor::deserialize_params(params)?)?;
478494
serialize(&ret, "total_supply result")
479495
}
480-
Some(Method::BalanceOf) => {
496+
Some(Method::BalanceOf) | Some(Method::BalanceOfExported) => {
481497
let ret = Self::balance_of(rt, cbor::deserialize_params(params)?)?;
482498
serialize(&ret, "balance_of result")
483499
}
484-
Some(Method::Transfer) => {
500+
Some(Method::Transfer) | Some(Method::TransferExported) => {
485501
let ret = Self::transfer(rt, cbor::deserialize_params(params)?)?;
486502
serialize(&ret, "transfer result")
487503
}
488-
Some(Method::TransferFrom) => {
504+
Some(Method::TransferFrom) | Some(Method::TransferFromExported) => {
489505
let ret = Self::transfer_from(rt, cbor::deserialize_params(params)?)?;
490506
serialize(&ret, "transfer_from result")
491507
}
492-
Some(Method::IncreaseAllowance) => {
508+
Some(Method::IncreaseAllowance) | Some(Method::IncreaseAllowanceExported) => {
493509
let ret = Self::increase_allowance(rt, cbor::deserialize_params(params)?)?;
494510
serialize(&ret, "increase_allowance result")
495511
}
496-
Some(Method::DecreaseAllowance) => {
512+
Some(Method::DecreaseAllowance) | Some(Method::DecreaseAllowanceExported) => {
497513
let ret = Self::decrease_allowance(rt, cbor::deserialize_params(params)?)?;
498514
serialize(&ret, "decrease_allowance result")
499515
}
500-
Some(Method::RevokeAllowance) => {
516+
Some(Method::RevokeAllowance) | Some(Method::RevokeAllowanceExported) => {
501517
Self::revoke_allowance(rt, cbor::deserialize_params(params)?)?;
502518
Ok(RawBytes::default())
503519
}
504-
Some(Method::Burn) => {
520+
Some(Method::Burn) | Some(Method::BurnExported) => {
505521
let ret = Self::burn(rt, cbor::deserialize_params(params)?)?;
506522
serialize(&ret, "burn result")
507523
}
508-
Some(Method::BurnFrom) => {
524+
Some(Method::BurnFrom) | Some(Method::BurnFromExported) => {
509525
let ret = Self::burn_from(rt, cbor::deserialize_params(params)?)?;
510526
serialize(&ret, "burn_from result")
511527
}
512-
Some(Method::Allowance) => {
528+
Some(Method::Allowance) | Some(Method::AllowanceExported) => {
513529
let ret = Self::allowance(rt, cbor::deserialize_params(params)?)?;
514530
serialize(&ret, "allowance result")
515531
}

actors/datacap/tests/datacap_actor_test.rs

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@ mod mint {
3434

3535
use fil_actor_datacap::{Actor, Method, MintParams, INFINITE_ALLOWANCE};
3636
use fil_actors_runtime::cbor::serialize;
37-
use fil_actors_runtime::test_utils::{expect_abort_contains_message, MARKET_ACTOR_CODE_ID};
37+
use fil_actors_runtime::test_utils::{
38+
expect_abort_contains_message, make_identity_cid, MARKET_ACTOR_CODE_ID,
39+
};
3840
use fil_actors_runtime::{STORAGE_MARKET_ACTOR_ADDR, VERIFIED_REGISTRY_ACTOR_ADDR};
3941
use fvm_ipld_encoding::RawBytes;
4042
use std::ops::Sub;
@@ -62,6 +64,21 @@ mod mint {
6264
h.check_state(&rt);
6365
}
6466

67+
#[test]
68+
fn requires_builtin_caller() {
69+
let (mut rt, h) = make_harness();
70+
let amt = TokenAmount::from_whole(1);
71+
let params = MintParams { to: *ALICE, amount: amt, operators: vec![] };
72+
73+
rt.set_caller(make_identity_cid(b"1234"), Address::new_id(1000));
74+
expect_abort_contains_message(
75+
ExitCode::USR_FORBIDDEN,
76+
"must be built-in",
77+
rt.call::<Actor>(Method::Mint as MethodNum, &serialize(&params, "params").unwrap()),
78+
);
79+
h.check_state(&rt);
80+
}
81+
6582
#[test]
6683
fn requires_verifreg_caller() {
6784
let (mut rt, h) = make_harness();
@@ -189,15 +206,33 @@ mod transfer {
189206
mod destroy {
190207
use crate::{make_harness, ALICE, BOB};
191208
use fil_actor_datacap::DestroyParams;
192-
use fil_actors_runtime::test_utils::{expect_abort_contains_message, ACCOUNT_ACTOR_CODE_ID};
209+
use fil_actors_runtime::test_utils::{
210+
expect_abort_contains_message, make_identity_cid, ACCOUNT_ACTOR_CODE_ID,
211+
};
193212
use fil_actors_runtime::VERIFIED_REGISTRY_ACTOR_ADDR;
213+
use fvm_shared::address::Address;
194214
use fvm_shared::econ::TokenAmount;
195215
use fvm_shared::MethodNum;
196216

197217
use fil_actor_datacap::{Actor, Method};
198218
use fil_actors_runtime::cbor::serialize;
199219
use fvm_shared::error::ExitCode;
200220

221+
#[test]
222+
fn requires_builtin_caller() {
223+
let (mut rt, h) = make_harness();
224+
let amt = TokenAmount::from_whole(1);
225+
let params = DestroyParams { owner: *ALICE, amount: amt };
226+
227+
rt.set_caller(make_identity_cid(b"1234"), Address::new_id(1000));
228+
expect_abort_contains_message(
229+
ExitCode::USR_FORBIDDEN,
230+
"must be built-in",
231+
rt.call::<Actor>(Method::Destroy as MethodNum, &serialize(&params, "params").unwrap()),
232+
);
233+
h.check_state(&rt);
234+
}
235+
201236
#[test]
202237
fn only_governor_allowed() {
203238
let (mut rt, h) = make_harness();

actors/datacap/tests/harness/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ pub struct Harness {
4141

4242
impl Harness {
4343
pub fn construct_and_verify(&self, rt: &mut MockRuntime, registry: &Address) {
44+
rt.set_caller(*SYSTEM_ACTOR_CODE_ID, SYSTEM_ACTOR_ADDR);
4445
rt.expect_validate_caller_addr(vec![SYSTEM_ACTOR_ADDR]);
4546
let ret = rt
4647
.call::<DataCapActor>(

actors/init/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ crate-type = ["cdylib", "lib"]
1515

1616
[dependencies]
1717
fil_actors_runtime = { version = "10.0.0-alpha.1", path = "../../runtime" }
18+
frc42_dispatch = "1.0.0"
1819
fvm_shared = { version = "2.0.0-alpha.2", default-features = false }
1920
fvm_ipld_hamt = "0.5.1"
2021
serde = { version = "1.0.136", features = ["derive"] }

actors/init/src/lib.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44
use cid::Cid;
55
use fil_actors_runtime::runtime::builtins::Type;
66
use fil_actors_runtime::runtime::{ActorCode, Runtime};
7-
use fil_actors_runtime::{actor_error, cbor, ActorContext, ActorError, SYSTEM_ACTOR_ADDR};
7+
use fil_actors_runtime::{
8+
actor_error, cbor, restrict_internal_api, ActorContext, ActorError, SYSTEM_ACTOR_ADDR,
9+
};
810
use fvm_ipld_encoding::RawBytes;
911
use fvm_shared::address::Address;
1012
use fvm_shared::{ActorID, MethodNum, METHOD_CONSTRUCTOR};
@@ -27,6 +29,8 @@ fil_actors_runtime::wasm_trampoline!(Actor);
2729
pub enum Method {
2830
Constructor = METHOD_CONSTRUCTOR,
2931
Exec = 2,
32+
// Method numbers derived from FRC-XXXX standards
33+
ExecExported = frc42_dispatch::method_hash!("Exec"),
3034
}
3135

3236
/// Init actor
@@ -102,12 +106,13 @@ impl ActorCode for Actor {
102106
where
103107
RT: Runtime,
104108
{
109+
restrict_internal_api(rt, method)?;
105110
match FromPrimitive::from_u64(method) {
106111
Some(Method::Constructor) => {
107112
Self::constructor(rt, cbor::deserialize_params(params)?)?;
108113
Ok(RawBytes::default())
109114
}
110-
Some(Method::Exec) => {
115+
Some(Method::Exec) | Some(Method::ExecExported) => {
111116
let res = Self::exec(rt, cbor::deserialize_params(params)?)?;
112117
Ok(RawBytes::serialize(res)?)
113118
}

actors/init/tests/init_actor_test.rs

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use fil_actor_init::testing::check_state_invariants;
66
use fil_actor_init::{
77
Actor as InitActor, ConstructorParams, ExecParams, ExecReturn, Method, State,
88
};
9+
use fil_actors_runtime::cbor::serialize;
910
use fil_actors_runtime::runtime::Runtime;
1011
use fil_actors_runtime::test_utils::*;
1112
use fil_actors_runtime::{
@@ -15,7 +16,7 @@ use fvm_ipld_encoding::RawBytes;
1516
use fvm_shared::address::Address;
1617
use fvm_shared::econ::TokenAmount;
1718
use fvm_shared::error::ExitCode;
18-
use fvm_shared::{HAMT_BIT_WIDTH, METHOD_CONSTRUCTOR};
19+
use fvm_shared::{MethodNum, HAMT_BIT_WIDTH, METHOD_CONSTRUCTOR};
1920
use num_traits::Zero;
2021
use serde::Serialize;
2122

@@ -287,7 +288,67 @@ fn sending_constructor_failure() {
287288
check_state(&rt);
288289
}
289290

291+
#[test]
292+
fn exec_restricted_correctly() {
293+
let mut rt = construct_runtime();
294+
construct_and_verify(&mut rt);
295+
296+
// set caller to not-builtin
297+
rt.set_caller(make_identity_cid(b"1234"), Address::new_id(1000));
298+
299+
// cannot call the unexported method num
300+
let fake_constructor_params =
301+
RawBytes::serialize(ConstructorParams { network_name: String::from("fake_param") })
302+
.unwrap();
303+
let exec_params = ExecParams {
304+
code_cid: *MULTISIG_ACTOR_CODE_ID,
305+
constructor_params: RawBytes::serialize(fake_constructor_params.clone()).unwrap(),
306+
};
307+
308+
expect_abort_contains_message(
309+
ExitCode::USR_FORBIDDEN,
310+
"must be built-in",
311+
rt.call::<InitActor>(
312+
Method::Exec as MethodNum,
313+
&serialize(&exec_params, "params").unwrap(),
314+
),
315+
);
316+
317+
// can call the exported method num
318+
319+
// Assign addresses
320+
let unique_address = Address::new_actor(b"multisig");
321+
rt.new_actor_addr = Some(unique_address);
322+
323+
// Next id
324+
let expected_id = 100;
325+
let expected_id_addr = Address::new_id(expected_id);
326+
rt.expect_create_actor(*MULTISIG_ACTOR_CODE_ID, expected_id);
327+
328+
// Expect a send to the multisig actor constructor
329+
rt.expect_send(
330+
expected_id_addr,
331+
METHOD_CONSTRUCTOR,
332+
RawBytes::serialize(&fake_constructor_params).unwrap(),
333+
TokenAmount::zero(),
334+
RawBytes::default(),
335+
ExitCode::OK,
336+
);
337+
338+
rt.expect_validate_caller_any();
339+
340+
let ret = rt
341+
.call::<InitActor>(Method::ExecExported as u64, &RawBytes::serialize(&exec_params).unwrap())
342+
.unwrap();
343+
let exec_ret: ExecReturn = RawBytes::deserialize(&ret).unwrap();
344+
assert_eq!(unique_address, exec_ret.robust_address, "Robust address does not macth");
345+
assert_eq!(expected_id_addr, exec_ret.id_address, "Id address does not match");
346+
check_state(&rt);
347+
rt.verify();
348+
}
349+
290350
fn construct_and_verify(rt: &mut MockRuntime) {
351+
rt.set_caller(*SYSTEM_ACTOR_CODE_ID, SYSTEM_ACTOR_ADDR);
291352
rt.expect_validate_caller_addr(vec![SYSTEM_ACTOR_ADDR]);
292353
let params = ConstructorParams { network_name: "mock".to_string() };
293354
let ret =

actors/market/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ fil_actors_runtime = { version = "10.0.0-alpha.1", path = "../../runtime"}
1818

1919
anyhow = "1.0.65"
2020
cid = { version = "0.8.3", default-features = false, features = ["serde-codec"] }
21+
frc42_dispatch = "1.0.0"
2122
frc46_token = "1.1.0"
2223
fvm_ipld_bitfield = "0.5.2"
2324
fvm_ipld_blockstore = "0.1.1"

actors/market/src/lib.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,10 @@ use fil_actors_runtime::cbor::{deserialize, serialize, serialize_vec};
3030
use fil_actors_runtime::runtime::builtins::Type;
3131
use fil_actors_runtime::runtime::{ActorCode, Policy, Runtime};
3232
use fil_actors_runtime::{
33-
actor_error, cbor, ActorContext, ActorDowncast, ActorError, AsActorError,
34-
BURNT_FUNDS_ACTOR_ADDR, CALLER_TYPES_SIGNABLE, CRON_ACTOR_ADDR, DATACAP_TOKEN_ACTOR_ADDR,
35-
REWARD_ACTOR_ADDR, STORAGE_POWER_ACTOR_ADDR, SYSTEM_ACTOR_ADDR, VERIFIED_REGISTRY_ACTOR_ADDR,
33+
actor_error, cbor, restrict_internal_api, ActorContext, ActorDowncast, ActorError,
34+
AsActorError, BURNT_FUNDS_ACTOR_ADDR, CALLER_TYPES_SIGNABLE, CRON_ACTOR_ADDR,
35+
DATACAP_TOKEN_ACTOR_ADDR, REWARD_ACTOR_ADDR, STORAGE_POWER_ACTOR_ADDR, SYSTEM_ACTOR_ADDR,
36+
VERIFIED_REGISTRY_ACTOR_ADDR,
3637
};
3738

3839
use crate::ext::verifreg::{AllocationID, AllocationRequest};
@@ -71,6 +72,9 @@ pub enum Method {
7172
OnMinerSectorsTerminate = 7,
7273
ComputeDataCommitment = 8,
7374
CronTick = 9,
75+
// Method numbers derived from FRC-XXXX standards
76+
AddBalanceExported = frc42_dispatch::method_hash!("AddBalance"),
77+
WithdrawBalanceExported = frc42_dispatch::method_hash!("WithdrawBalance"),
7478
}
7579

7680
/// Market Actor
@@ -1389,16 +1393,17 @@ impl ActorCode for Actor {
13891393
where
13901394
RT: Runtime,
13911395
{
1396+
restrict_internal_api(rt, method)?;
13921397
match FromPrimitive::from_u64(method) {
13931398
Some(Method::Constructor) => {
13941399
Self::constructor(rt)?;
13951400
Ok(RawBytes::default())
13961401
}
1397-
Some(Method::AddBalance) => {
1402+
Some(Method::AddBalance) | Some(Method::AddBalanceExported) => {
13981403
Self::add_balance(rt, cbor::deserialize_params(params)?)?;
13991404
Ok(RawBytes::default())
14001405
}
1401-
Some(Method::WithdrawBalance) => {
1406+
Some(Method::WithdrawBalance) | Some(Method::WithdrawBalanceExported) => {
14021407
let res = Self::withdraw_balance(rt, cbor::deserialize_params(params)?)?;
14031408
Ok(RawBytes::serialize(res)?)
14041409
}

0 commit comments

Comments
 (0)