Skip to content

Commit

Permalink
feat: multisig: accept arbitrary public messages (#1252)
Browse files Browse the repository at this point in the history
* accept arbitrary messages in multisig

* accept arbitrary messages in paych

* add tests for fallback method handler in account, multisig, and paych

* rustfmt

* clippy

* moar clippy

* leave paych unmolested

* names....

* Review Response

* Update fallback to mutable runtime

* Clippy

---------

Co-authored-by: zenground0 <ZenGround0@users.noreply.github.com>
Co-authored-by: ZenGround0 <5515260+ZenGround0@users.noreply.github.com>
  • Loading branch information
3 people authored Apr 7, 2023
1 parent bb01e4c commit 49db254
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 0 deletions.
37 changes: 37 additions & 0 deletions actors/account/tests/account_actor_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use fil_actor_account::types::AuthenticateMessageParams;
use fil_actor_account::{testing::check_state_invariants, Actor as AccountActor, Method, State};
use fil_actors_runtime::builtin::SYSTEM_ACTOR_ADDR;
use fil_actors_runtime::test_utils::*;
use fil_actors_runtime::FIRST_EXPORTED_METHOD_NUMBER;

#[test]
fn construction() {
Expand Down Expand Up @@ -158,6 +159,42 @@ fn authenticate_message() {
.unwrap());
}

#[test]
fn test_fallback() {
let rt = MockRuntime { receiver: Address::new_id(100), ..Default::default() };
rt.set_caller(*SYSTEM_ACTOR_CODE_ID, SYSTEM_ACTOR_ADDR);

let addr = Address::new_secp256k1(&[2; fvm_shared::address::SECP_PUB_LEN]).unwrap();
rt.expect_validate_caller_addr(vec![SYSTEM_ACTOR_ADDR]);
rt.call::<AccountActor>(
Method::Constructor as MethodNum,
IpldBlock::serialize_cbor(&addr).unwrap(),
)
.unwrap();

let state: State = rt.get_state();
assert_eq!(state.address, addr);

// this is arbitrary
let params = IpldBlock::serialize_cbor(&vec![1u8, 2u8, 3u8]).unwrap();

// accept >= 2<<24
rt.expect_validate_caller_any();
let result = rt.call::<AccountActor>(FIRST_EXPORTED_METHOD_NUMBER, params.clone()).unwrap();
assert!(result.is_none());

rt.expect_validate_caller_any();
let result = rt.call::<AccountActor>(FIRST_EXPORTED_METHOD_NUMBER + 1, params.clone()).unwrap();
assert!(result.is_none());

// reject < 1<<24
rt.expect_validate_caller_any();
let result = rt.call::<AccountActor>(FIRST_EXPORTED_METHOD_NUMBER - 1, params);
assert!(result.is_err());

rt.verify();
}

fn check_state(rt: &MockRuntime) {
let test_address = Address::new_id(1000);
let (_, acc) = check_state_invariants(&rt.get_state(), &test_address);
Expand Down
17 changes: 17 additions & 0 deletions actors/multisig/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@
use fvm_actor_utils::receiver::UniversalReceiverParams;
use std::collections::BTreeSet;

use fil_actors_runtime::FIRST_EXPORTED_METHOD_NUMBER;
use fvm_ipld_blockstore::Blockstore;
use fvm_ipld_encoding::ipld_block::IpldBlock;
use fvm_ipld_encoding::RawBytes;
use fvm_shared::address::Address;
use fvm_shared::econ::TokenAmount;
use fvm_shared::error::ExitCode;
use fvm_shared::MethodNum;
use fvm_shared::{HAMT_BIT_WIDTH, METHOD_CONSTRUCTOR};
use num_derive::FromPrimitive;
use num_traits::Zero;
Expand Down Expand Up @@ -445,6 +448,19 @@ impl Actor {
rt.validate_immediate_caller_accept_any()?;
Ok(())
}

pub fn fallback(
rt: &impl Runtime,
method: MethodNum,
_: Option<IpldBlock>,
) -> Result<Option<IpldBlock>, ActorError> {
rt.validate_immediate_caller_accept_any()?;
if method >= FIRST_EXPORTED_METHOD_NUMBER {
Ok(None)
} else {
Err(actor_error!(unhandled_message; "invalid method: {}", method))
}
}
}

fn execute_transaction_if_approved(
Expand Down Expand Up @@ -562,5 +578,6 @@ impl ActorCode for Actor {
ChangeNumApprovalsThreshold => change_num_approvals_threshold,
LockBalance => lock_balance,
UniversalReceiverHook => universal_receiver_hook,
_ => fallback [raw],
}
}
32 changes: 32 additions & 0 deletions actors/multisig/tests/multisig_actor_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use fil_actor_multisig::{
use fil_actors_runtime::cbor::serialize;
use fil_actors_runtime::runtime::Runtime;
use fil_actors_runtime::test_utils::*;
use fil_actors_runtime::FIRST_EXPORTED_METHOD_NUMBER;
use fil_actors_runtime::{INIT_ACTOR_ADDR, SYSTEM_ACTOR_ADDR};
use fvm_actor_utils::receiver::UniversalReceiverParams;
use fvm_ipld_encoding::ipld_block::IpldBlock;
Expand Down Expand Up @@ -2398,3 +2399,34 @@ fn token_receiver() {
fn to_ipld_block(p: RawBytes) -> Option<IpldBlock> {
Some(IpldBlock { codec: CBOR, data: p.to_vec() })
}

#[test]
fn test_fallback() {
let msig = Address::new_id(1000);
let anne = Address::new_id(101);
let bob = Address::new_id(102);

let rt = construct_runtime(msig);
let h = util::ActorHarness::new();
h.construct_and_verify(&rt, 2, 0, 0, vec![anne, bob]);

// this is arbitrary
let params = IpldBlock::serialize_cbor(&vec![1u8, 2u8, 3u8]).unwrap();

// accept >= 2<<24
rt.expect_validate_caller_any();
let result = rt.call::<MultisigActor>(FIRST_EXPORTED_METHOD_NUMBER, params.clone()).unwrap();
assert!(result.is_none());

rt.expect_validate_caller_any();
let result =
rt.call::<MultisigActor>(FIRST_EXPORTED_METHOD_NUMBER + 1, params.clone()).unwrap();
assert!(result.is_none());

// reject < 2<<24
rt.expect_validate_caller_any();
let result = rt.call::<MultisigActor>(FIRST_EXPORTED_METHOD_NUMBER - 1, params);
assert!(result.is_err());

rt.verify();
}

0 comments on commit 49db254

Please sign in to comment.