Skip to content

Commit 91cd5f8

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 a7cbe4c commit 91cd5f8

25 files changed

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

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();
@@ -188,15 +205,33 @@ mod transfer {
188205
mod destroy {
189206
use crate::{make_harness, ALICE, BOB};
190207
use fil_actor_datacap::DestroyParams;
191-
use fil_actors_runtime::test_utils::{expect_abort_contains_message, ACCOUNT_ACTOR_CODE_ID};
208+
use fil_actors_runtime::test_utils::{
209+
expect_abort_contains_message, make_identity_cid, ACCOUNT_ACTOR_CODE_ID,
210+
};
192211
use fil_actors_runtime::VERIFIED_REGISTRY_ACTOR_ADDR;
212+
use fvm_shared::address::Address;
193213
use fvm_shared::econ::TokenAmount;
194214
use fvm_shared::MethodNum;
195215

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

220+
#[test]
221+
fn requires_builtin_caller() {
222+
let (mut rt, h) = make_harness();
223+
let amt = TokenAmount::from_whole(1);
224+
let params = DestroyParams { owner: *ALICE, amount: amt };
225+
226+
rt.set_caller(make_identity_cid(b"1234"), Address::new_id(1000));
227+
expect_abort_contains_message(
228+
ExitCode::USR_FORBIDDEN,
229+
"must be built-in",
230+
rt.call::<Actor>(Method::Destroy as MethodNum, &serialize(&params, "params").unwrap()),
231+
);
232+
h.check_state(&rt);
233+
}
234+
200235
#[test]
201236
fn only_governor_allowed() {
202237
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 = "3.0.0-alpha.11", default-features = false }
1920
fvm_ipld_hamt = "0.6.1"
2021
serde = { version = "1.0.136", features = ["derive"] }

actors/init/src/lib.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ use std::iter;
66
use cid::Cid;
77
use fil_actors_runtime::runtime::{ActorCode, Runtime};
88
use fil_actors_runtime::{
9-
actor_error, cbor, ActorContext, ActorError, EAM_ACTOR_ADDR, SYSTEM_ACTOR_ADDR,
9+
actor_error, cbor, restrict_internal_api, ActorContext, ActorError, EAM_ACTOR_ADDR,
10+
SYSTEM_ACTOR_ADDR,
1011
};
1112
use fvm_ipld_encoding::RawBytes;
1213
use fvm_shared::address::Address;
@@ -33,6 +34,8 @@ pub enum Method {
3334
Exec4 = 3,
3435
#[cfg(feature = "m2-native")]
3536
InstallCode = 4,
37+
// Method numbers derived from FRC-XXXX standards
38+
ExecExported = frc42_dispatch::method_hash!("Exec"),
3639
}
3740

3841
/// Init actor
@@ -196,12 +199,13 @@ impl ActorCode for Actor {
196199
where
197200
RT: Runtime,
198201
{
202+
restrict_internal_api(rt, method)?;
199203
match FromPrimitive::from_u64(method) {
200204
Some(Method::Constructor) => {
201205
Self::constructor(rt, cbor::deserialize_params(params)?)?;
202206
Ok(RawBytes::default())
203207
}
204-
Some(Method::Exec) => {
208+
Some(Method::Exec) | Some(Method::ExecExported) => {
205209
let res = Self::exec(rt, cbor::deserialize_params(params)?)?;
206210
Ok(RawBytes::serialize(res)?)
207211
}

actors/init/tests/init_actor_test.rs

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use fil_actor_init::{
77
Actor as InitActor, ConstructorParams, Exec4Params, Exec4Return, ExecParams, ExecReturn,
88
Method, State,
99
};
10+
use fil_actors_runtime::cbor::serialize;
1011
use fil_actors_runtime::runtime::Runtime;
1112
use fil_actors_runtime::{test_utils::*, EAM_ACTOR_ADDR, EAM_ACTOR_ID};
1213
use fil_actors_runtime::{
@@ -16,7 +17,7 @@ use fvm_ipld_encoding::RawBytes;
1617
use fvm_shared::address::Address;
1718
use fvm_shared::econ::TokenAmount;
1819
use fvm_shared::error::ExitCode;
19-
use fvm_shared::{HAMT_BIT_WIDTH, METHOD_CONSTRUCTOR};
20+
use fvm_shared::{MethodNum, HAMT_BIT_WIDTH, METHOD_CONSTRUCTOR};
2021
use num_traits::Zero;
2122
use serde::Serialize;
2223

@@ -283,6 +284,65 @@ fn sending_constructor_failure() {
283284
check_state(&rt);
284285
}
285286

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

332392
fn construct_and_verify(rt: &mut MockRuntime) {
393+
rt.set_caller(*SYSTEM_ACTOR_CODE_ID, SYSTEM_ACTOR_ADDR);
333394
rt.expect_validate_caller_addr(vec![SYSTEM_ACTOR_ADDR]);
334395
let params = ConstructorParams { network_name: "mock".to_string() };
335396
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.4"
2324
fvm_ipld_blockstore = "0.1.1"

0 commit comments

Comments
 (0)