Skip to content

Commit

Permalink
Added check for actor existence in resolve_to_actor_id (#992)
Browse files Browse the repository at this point in the history
  • Loading branch information
sudo-shashank authored Feb 23, 2023
1 parent fb759f8 commit 05bc73f
Show file tree
Hide file tree
Showing 7 changed files with 94 additions and 61 deletions.
10 changes: 5 additions & 5 deletions actors/multisig/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ impl Actor {
let mut resolved_signers = Vec::with_capacity(params.signers.len());
let mut dedup_signers = BTreeSet::new();
for signer in &params.signers {
let resolved = resolve_to_actor_id(rt, signer)?;
let resolved = resolve_to_actor_id(rt, signer, true)?;
if !dedup_signers.insert(resolved) {
return Err(
actor_error!(illegal_argument; "duplicate signer not allowed: {}", signer),
Expand Down Expand Up @@ -257,7 +257,7 @@ impl Actor {
pub fn add_signer(rt: &mut impl Runtime, params: AddSignerParams) -> Result<(), ActorError> {
let receiver = rt.message().receiver();
rt.validate_immediate_caller_is(std::iter::once(&receiver))?;
let resolved_new_signer = resolve_to_actor_id(rt, &params.signer)?;
let resolved_new_signer = resolve_to_actor_id(rt, &params.signer, true)?;

rt.transaction(|st: &mut State, _| {
if st.signers.len() >= SIGNERS_MAX {
Expand Down Expand Up @@ -288,7 +288,7 @@ impl Actor {
) -> Result<(), ActorError> {
let receiver = rt.message().receiver();
rt.validate_immediate_caller_is(std::iter::once(&receiver))?;
let resolved_old_signer = resolve_to_actor_id(rt, &params.signer)?;
let resolved_old_signer = resolve_to_actor_id(rt, &params.signer, false)?;

rt.transaction(|st: &mut State, rt| {
if !st.is_signer(&Address::new_id(resolved_old_signer)) {
Expand Down Expand Up @@ -335,8 +335,8 @@ impl Actor {
pub fn swap_signer(rt: &mut impl Runtime, params: SwapSignerParams) -> Result<(), ActorError> {
let receiver = rt.message().receiver();
rt.validate_immediate_caller_is(std::iter::once(&receiver))?;
let from_resolved = resolve_to_actor_id(rt, &params.from)?;
let to_resolved = resolve_to_actor_id(rt, &params.to)?;
let from_resolved = resolve_to_actor_id(rt, &params.from, false)?;
let to_resolved = resolve_to_actor_id(rt, &params.to, true)?;

rt.transaction(|st: &mut State, rt| {
if !st.is_signer(&Address::new_id(from_resolved)) {
Expand Down
22 changes: 20 additions & 2 deletions actors/multisig/tests/multisig_actor_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,42 @@ use fil_actors_runtime::runtime::Runtime;
use fil_actors_runtime::test_utils::*;
use fil_actors_runtime::{INIT_ACTOR_ADDR, SYSTEM_ACTOR_ADDR};
use fvm_actor_utils::receiver::UniversalReceiverParams;
use fvm_ipld_encoding::ipld_block::IpldBlock;
use fvm_ipld_encoding::tuple::*;
use fvm_ipld_encoding::{RawBytes, CBOR};
use fvm_shared::address::{Address, BLS_PUB_LEN};

use fvm_ipld_encoding::ipld_block::IpldBlock;
use fvm_shared::bigint::Zero;
use fvm_shared::clock::ChainEpoch;
use fvm_shared::econ::TokenAmount;
use fvm_shared::error::ExitCode;
use fvm_shared::{MethodNum, METHOD_SEND};
use std::collections::HashMap;

mod util;

const TEST_MSIG_ADDR: u64 = 100;
const TEST_ANNE_ADDR: u64 = 101;
const TEST_BOB_ADDR: u64 = 102;
const TEST_CHUCK_ADDR: u64 = 103;
const TEST_DARLENE_ADDR: u64 = 104;

fn construct_runtime(receiver: Address) -> MockRuntime {
let test_msig_addr = Address::new_id(TEST_MSIG_ADDR);
let test_anne_addr = Address::new_id(TEST_ANNE_ADDR);
let test_bob_addr = Address::new_id(TEST_BOB_ADDR);
let test_chuck_addr = Address::new_id(TEST_CHUCK_ADDR);
let test_darlene_addr = Address::new_id(TEST_DARLENE_ADDR);
let mut actor_code_cids = HashMap::default();
actor_code_cids.insert(test_msig_addr, *ACCOUNT_ACTOR_CODE_ID);
actor_code_cids.insert(test_anne_addr, *ACCOUNT_ACTOR_CODE_ID);
actor_code_cids.insert(test_bob_addr, *ACCOUNT_ACTOR_CODE_ID);
actor_code_cids.insert(test_chuck_addr, *ACCOUNT_ACTOR_CODE_ID);
actor_code_cids.insert(test_darlene_addr, *ACCOUNT_ACTOR_CODE_ID);
MockRuntime {
receiver,
caller: SYSTEM_ACTOR_ADDR,
caller_type: *SYSTEM_ACTOR_CODE_ID,
actor_code_cids,
..Default::default()
}
}
Expand Down
25 changes: 4 additions & 21 deletions actors/paych/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use fil_actors_runtime::runtime::builtins::Type;
use fil_actors_runtime::runtime::{ActorCode, Runtime};
use fil_actors_runtime::{
actor_dispatch, actor_error, extract_send_result, resolve_to_actor_id, ActorDowncast,
ActorError, Array, AsActorError,
ActorError, Array,
};
use fvm_ipld_blockstore::Blockstore;
use fvm_ipld_encoding::CBOR;
Expand Down Expand Up @@ -54,16 +54,9 @@ impl Actor {
// behalf of the payer/payee.
rt.validate_immediate_caller_type(std::iter::once(&Type::Init))?;

// Resolve both parties, confirming they exist in the state tree.
let to = Self::resolve_address(rt, &params.to)
.with_context_code(ExitCode::USR_ILLEGAL_ARGUMENT, || {
format!("to address not found {}", params.to)
})?;

let from = Self::resolve_address(rt, &params.from)
.with_context_code(ExitCode::USR_ILLEGAL_ARGUMENT, || {
format!("from address not found {}", params.from)
})?;
// Check both parties are capable of signing vouchers
let to = resolve_to_actor_id(rt, &params.to, true).map(Address::new_id)?;
let from = resolve_to_actor_id(rt, &params.from, true).map(Address::new_id)?;

let empty_arr_cid =
Array::<(), _>::new_with_bit_width(rt.store(), LANE_STATES_AMT_BITWIDTH)
Expand All @@ -76,16 +69,6 @@ impl Actor {
Ok(())
}

/// Resolves an address to a canonical ID address and confirms it exists in the state tree.
fn resolve_address(rt: &mut impl Runtime, raw: &Address) -> Result<Address, ActorError> {
let resolved = resolve_to_actor_id(rt, raw)?;

// so long as we can find code for this, return `resolved`
rt.get_actor_code_cid(&resolved)
.map(|_| Address::new_id(resolved))
.ok_or_else(|| actor_error!(illegal_argument, "no code for address {}", resolved))
}

pub fn update_channel_state(
rt: &mut impl Runtime,
params: UpdateChannelStateParams,
Expand Down
2 changes: 1 addition & 1 deletion actors/paych/tests/paych_actor_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ mod paych_constructor {
&mut rt,
METHOD_CONSTRUCTOR,
IpldBlock::serialize_cbor(&params).unwrap(),
ExitCode::USR_ILLEGAL_ARGUMENT,
ExitCode::USR_NOT_FOUND,
);
}

Expand Down
12 changes: 6 additions & 6 deletions actors/verifreg/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ impl Actor {
));
}

let verifier = resolve_to_actor_id(rt, &params.address)?;
let verifier = resolve_to_actor_id(rt, &params.address, true)?;

let verifier = Address::new_id(verifier);

Expand Down Expand Up @@ -135,7 +135,7 @@ impl Actor {
}

pub fn remove_verifier(rt: &mut impl Runtime, params: Address) -> Result<(), ActorError> {
let verifier = resolve_to_actor_id(rt, &params)?;
let verifier = resolve_to_actor_id(rt, &params, false)?;
let verifier = Address::new_id(verifier);

let state: State = rt.state()?;
Expand All @@ -162,7 +162,7 @@ impl Actor {
));
}

let client = resolve_to_actor_id(rt, &params.address)?;
let client = resolve_to_actor_id(rt, &params.address, true)?;
let client = Address::new_id(client);

let st: State = rt.state()?;
Expand Down Expand Up @@ -216,13 +216,13 @@ impl Actor {
rt: &mut impl Runtime,
params: RemoveDataCapParams,
) -> Result<RemoveDataCapReturn, ActorError> {
let client = resolve_to_actor_id(rt, &params.verified_client_to_remove)?;
let client = resolve_to_actor_id(rt, &params.verified_client_to_remove, false)?;
let client = Address::new_id(client);

let verifier_1 = resolve_to_actor_id(rt, &params.verifier_request_1.verifier)?;
let verifier_1 = resolve_to_actor_id(rt, &params.verifier_request_1.verifier, true)?;
let verifier_1 = Address::new_id(verifier_1);

let verifier_2 = resolve_to_actor_id(rt, &params.verifier_request_2.verifier)?;
let verifier_2 = resolve_to_actor_id(rt, &params.verifier_request_2.verifier, true)?;
let verifier_2 = Address::new_id(verifier_2);

if verifier_1 == verifier_2 {
Expand Down
51 changes: 36 additions & 15 deletions actors/verifreg/tests/harness/mod.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,3 @@
use frc46_token::receiver::{FRC46TokenReceived, FRC46_TOKEN_TYPE};
use frc46_token::token::types::{BurnParams, BurnReturn, TransferParams};
use frc46_token::token::TOKEN_PRECISION;
use fvm_actor_utils::receiver::UniversalReceiverParams;
use fvm_ipld_encoding::RawBytes;
use fvm_shared::address::Address;
use fvm_shared::bigint::bigint_ser::{BigIntDe, BigIntSer};
use fvm_shared::clock::ChainEpoch;
use fvm_shared::econ::TokenAmount;
use fvm_shared::error::ExitCode;
use fvm_shared::piece::PaddedPieceSize;
use fvm_shared::sector::SectorNumber;
use fvm_shared::{ActorID, MethodNum, HAMT_BIT_WIDTH};
use num_traits::{ToPrimitive, Zero};

use fil_actor_verifreg::testing::check_state_invariants;
use fil_actor_verifreg::{
ext, Actor as VerifregActor, AddVerifiedClientParams, AddVerifierParams, Allocation,
Expand All @@ -33,15 +18,51 @@ use fil_actors_runtime::{
make_empty_map, ActorError, AsActorError, BatchReturn, DATACAP_TOKEN_ACTOR_ADDR,
STORAGE_MARKET_ACTOR_ADDR, SYSTEM_ACTOR_ADDR, VERIFIED_REGISTRY_ACTOR_ADDR,
};
use frc46_token::receiver::{FRC46TokenReceived, FRC46_TOKEN_TYPE};
use frc46_token::token::types::{BurnParams, BurnReturn, TransferParams};
use frc46_token::token::TOKEN_PRECISION;
use fvm_actor_utils::receiver::UniversalReceiverParams;
use fvm_ipld_encoding::ipld_block::IpldBlock;
use fvm_ipld_encoding::RawBytes;
use fvm_shared::address::Address;
use fvm_shared::bigint::bigint_ser::{BigIntDe, BigIntSer};
use fvm_shared::clock::ChainEpoch;
use fvm_shared::econ::TokenAmount;
use fvm_shared::error::ExitCode;
use fvm_shared::piece::PaddedPieceSize;
use fvm_shared::sector::SectorNumber;
use fvm_shared::{ActorID, MethodNum, HAMT_BIT_WIDTH};
use num_traits::{ToPrimitive, Zero};
use std::collections::HashMap;

pub const ROOT_ADDR: Address = Address::new_id(101);

const TEST_VERIFIER_ADDR: u64 = 201;
const TEST_VERIFIER2_ADDR: u64 = 202;
const TEST_CLIENT_ADDR: u64 = 301;
const TEST_CLIENT2_ADDR: u64 = 302;
const TEST_CLIENT3_ADDR: u64 = 303;
const TEST_CLIENT4_ADDR: u64 = 304;

pub fn new_runtime() -> MockRuntime {
let test_verifier_addr = Address::new_id(TEST_VERIFIER_ADDR);
let test_verifier2_addr = Address::new_id(TEST_VERIFIER2_ADDR);
let test_client_addr = Address::new_id(TEST_CLIENT_ADDR);
let test_client2_addr = Address::new_id(TEST_CLIENT2_ADDR);
let test_client3_addr = Address::new_id(TEST_CLIENT3_ADDR);
let test_client4_addr = Address::new_id(TEST_CLIENT4_ADDR);
let mut actor_code_cids = HashMap::default();
actor_code_cids.insert(test_verifier_addr, *ACCOUNT_ACTOR_CODE_ID);
actor_code_cids.insert(test_verifier2_addr, *ACCOUNT_ACTOR_CODE_ID);
actor_code_cids.insert(test_client_addr, *ACCOUNT_ACTOR_CODE_ID);
actor_code_cids.insert(test_client2_addr, *ACCOUNT_ACTOR_CODE_ID);
actor_code_cids.insert(test_client3_addr, *ACCOUNT_ACTOR_CODE_ID);
actor_code_cids.insert(test_client4_addr, *ACCOUNT_ACTOR_CODE_ID);
MockRuntime {
receiver: VERIFIED_REGISTRY_ACTOR_ADDR,
caller: SYSTEM_ACTOR_ADDR,
caller_type: *SYSTEM_ACTOR_CODE_ID,
actor_code_cids,
..Default::default()
}
}
Expand Down
33 changes: 22 additions & 11 deletions runtime/src/builtin/shared.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,22 +21,33 @@ pub const FIRST_ACTOR_SPECIFIC_EXIT_CODE: u32 = 32;
pub fn resolve_to_actor_id(
rt: &mut impl Runtime,
address: &Address,
check_existence: bool,
) -> Result<ActorID, ActorError> {
let mut actor_id = None;
// if we are able to resolve it to an ID address, return the resolved address
if let Some(id) = rt.resolve_address(address) {
return Ok(id);
}
actor_id = Some(id)
} else {
// send 0 balance to the account so an ID address for it is created and then try to resolve
extract_send_result(rt.send_simple(
address,
METHOD_SEND,
Default::default(),
Default::default(),
))
.with_context(|| format!("failed to send zero balance to address {}", address))?;

// send 0 balance to the account so an ID address for it is created and then try to resolve
extract_send_result(rt.send_simple(
address,
METHOD_SEND,
Default::default(),
Default::default(),
))
.with_context(|| format!("failed to send zero balance to address {}", address))?;
if let Some(id) = rt.resolve_address(address) {
actor_id = Some(id)
}
}

if let Some(id) = rt.resolve_address(address) {
if let Some(id) = actor_id {
// check for actor existence
if check_existence {
rt.get_actor_code_cid(&id)
.ok_or_else(|| actor_error!(not_found, "no code for address {}", address))?;
}
return Ok(id);
}

Expand Down

0 comments on commit 05bc73f

Please sign in to comment.