Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EVM: test send error changes #1099

Merged
merged 4 commits into from
Jan 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 69 additions & 5 deletions actors/evm/tests/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use fvm_shared::address::Address as FILAddress;
use fvm_shared::address::Address;
use fvm_shared::bigint::Zero;
use fvm_shared::econ::TokenAmount;
use fvm_shared::error::ExitCode;
use fvm_shared::error::{ErrorNumber, ExitCode};
use fvm_shared::sys::SendFlags;
use fvm_shared::{ActorID, MethodNum, METHOD_SEND};
use once_cell::sync::Lazy;
Expand Down Expand Up @@ -203,6 +203,7 @@ fn test_call() {
IpldBlock::serialize_cbor(&BytesSer(&return_data))
.expect("failed to serialize return data"),
ExitCode::OK,
None,
);

let result = util::invoke_contract(&mut rt, &contract_params);
Expand Down Expand Up @@ -273,6 +274,7 @@ fn test_call_convert_to_send() {
IpldBlock::serialize_cbor(&BytesSer(&return_data))
.expect("failed to serialize return data"),
ExitCode::OK,
None,
);

let result = util::invoke_contract(&mut rt, &contract_params);
Expand Down Expand Up @@ -408,6 +410,7 @@ return
SendFlags::empty(),
Some(large_ret.clone()),
ExitCode::OK,
None,
);

rt.expect_gas_available(10_000_000_000);
Expand Down Expand Up @@ -604,6 +607,7 @@ fn test_callactor_inner(method_num: MethodNum, exit_code: ExitCode, valid_call_i
send_flags,
Some(send_return.clone()),
exit_code,
None,
);
}

Expand All @@ -612,7 +616,7 @@ fn test_callactor_inner(method_num: MethodNum, exit_code: ExitCode, valid_call_i
v[..4].copy_from_slice(&send_return.data);

let expect = CallActorReturn {
exit_code,
send_exit_code: U256::from(exit_code.value()),
codec: send_return.codec,
data_offset: 96,
data_size: send_return.data.len() as u32,
Expand Down Expand Up @@ -683,6 +687,7 @@ fn call_actor_weird_offset() {
SendFlags::empty(),
None,
ExitCode::OK,
None,
);

let precompile_return = CallActorReturn::default();
Expand Down Expand Up @@ -733,6 +738,7 @@ fn call_actor_overlapping() {
SendFlags::empty(),
None,
ExitCode::OK,
None,
);

test.input = call_params.into();
Expand Down Expand Up @@ -775,12 +781,59 @@ fn call_actor_id_with_full_address() {
SendFlags::empty(),
None,
ExitCode::OK,
None,
);

test.input = call_params.into();
test.run_test_expecting(&mut rt, CallActorReturn::default(), util::PrecompileExit::Success);
}

#[test]
fn call_actor_syscall_error() {
let contract = {
let (init, body) = util::PrecompileTest::test_runner_assembly();
asm::new_contract("call_actor-precompile-test", &init, &body).unwrap()
};
let mut rt = util::construct_and_verify(contract);
let addr = Address::new_delegated(1234, b"foobarboxy").unwrap();

let mut call_params = CallActorParams::default();
call_params.set_addr(CallActorParams::EMPTY_PARAM_ADDR_OFFSET, addr.to_bytes());

let mut test = util::PrecompileTest {
precompile_address: util::NativePrecompile::CallActor.eth_address(),
output_size: 32,
gas_avaliable: 10_000_000_000u64,
call_op: util::PrecompileCallOpcode::DelegateCall,
// overwritten in tests
expected_return: vec![],
expected_exit_code: util::PrecompileExit::Success,
input: call_params.clone().into(),
};

let syscall_exit = ErrorNumber::NotFound;

let expect = CallActorReturn {
send_exit_code: U256::from(syscall_exit as u32).i256_neg(),
..Default::default()
};

rt.expect_send_generalized(
addr,
0,
None,
TokenAmount::zero(),
Some(0),
SendFlags::empty(),
None,
ExitCode::new(0xffff),
Some(syscall_exit),
);

test.input = call_params.into();
test.run_test_expecting(&mut rt, expect, util::PrecompileExit::Success);
}

#[cfg(test)]
mod call_actor_invalid {
use super::*;
Expand Down Expand Up @@ -988,13 +1041,19 @@ impl From<CallActorParams> for Vec<u8> {

impl Default for CallActorReturn {
fn default() -> Self {
Self { exit_code: ExitCode::OK, codec: 0, data_offset: 3 * 32, data_size: 0, data: vec![] }
Self {
send_exit_code: U256::from(ExitCode::OK.value()),
codec: 0,
data_offset: 3 * 32,
data_size: 0,
data: vec![],
}
}
}

#[derive(Debug, PartialEq, Eq)]
struct CallActorReturn {
exit_code: ExitCode,
send_exit_code: U256,
codec: u64,
data_offset: u32,
data_size: u32,
Expand All @@ -1003,7 +1062,9 @@ struct CallActorReturn {

impl From<CallActorReturn> for Vec<u8> {
fn from(src: CallActorReturn) -> Self {
let exit_code = U256::from(src.exit_code.value());
// precompile will return negative number for send errors
let exit_code = src.send_exit_code;

let codec = U256::from(src.codec);
let offset = U256::from(src.data_offset);
let len = U256::from(src.data_size);
Expand Down Expand Up @@ -1056,6 +1117,7 @@ fn call_actor_solidity() {
SendFlags::empty(),
Some(IpldBlock { codec: 0, data: expected_return.clone() }),
ExitCode::OK,
None,
);

let (success, exit, codec, ret_val): (bool, ethers::types::I256, u64, Bytes) =
Expand Down Expand Up @@ -1098,6 +1160,7 @@ fn call_actor_solidity() {
SendFlags::empty(),
Some(IpldBlock { codec: 0, data: expected_return.clone() }),
ExitCode::OK,
None,
);

let (success, exit, codec, ret_val): (bool, ethers::types::I256, u64, Bytes) =
Expand Down Expand Up @@ -1140,6 +1203,7 @@ fn call_actor_send_solidity() {
SendFlags::empty(),
Some(IpldBlock { codec: 0, data: expected_return.clone() }),
ExitCode::OK,
None,
);

let (success, exit, codec, ret_val): (bool, ethers::types::I256, u64, Bytes) =
Expand Down
2 changes: 2 additions & 0 deletions actors/evm/tests/delegate_call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ fn test_delegate_call_caller() {
SendFlags::READ_ONLY,
IpldBlock::serialize_cbor(&EMPTY_ARR_CID).expect("failed to serialize bytecode hash"),
ExitCode::OK,
None,
);

rt.expect_send_generalized(
Expand All @@ -129,6 +130,7 @@ fn test_delegate_call_caller() {
IpldBlock::serialize_cbor(&BytesSer(&return_data.to_bytes()))
.expect("failed to serialize return data"),
ExitCode::OK,
None,
);

let result = util::invoke_contract(&mut rt, &contract_params);
Expand Down
5 changes: 5 additions & 0 deletions actors/evm/tests/ext_opcodes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ non_existent:
SendFlags::READ_ONLY,
IpldBlock::serialize_cbor(&bytecode_cid).unwrap(),
ExitCode::OK,
None,
);

let result = util::invoke_contract(&mut rt, &method);
Expand Down Expand Up @@ -256,6 +257,7 @@ account:
SendFlags::READ_ONLY,
IpldBlock::serialize_cbor(&bytecode_hash).unwrap(),
ExitCode::OK,
None,
);

// Evm code
Expand Down Expand Up @@ -402,6 +404,7 @@ precompile:
SendFlags::READ_ONLY,
IpldBlock::serialize_cbor(&bytecode_cid).unwrap(),
ExitCode::OK,
None,
);

let result = util::invoke_contract(&mut rt, &util::dispatch_num_word(0));
Expand Down Expand Up @@ -477,6 +480,7 @@ init_extsize:
SendFlags::READ_ONLY,
IpldBlock::serialize_cbor(&BytecodeHash::EMPTY).unwrap(),
ExitCode::OK,
None,
);

rt.store.put_keyed(&EMPTY_ARR_CID, &[]).unwrap();
Expand All @@ -489,6 +493,7 @@ init_extsize:
SendFlags::READ_ONLY,
IpldBlock::serialize_cbor(&EMPTY_ARR_CID).unwrap(),
ExitCode::OK,
None,
);
});

Expand Down
8 changes: 8 additions & 0 deletions runtime/src/test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,7 @@ pub struct ExpectedMessage {
// returns from applying expectedMessage
pub send_return: Option<IpldBlock>,
pub exit_code: ExitCode,
pub send_error: Option<ErrorNumber>,
}

#[derive(Debug)]
Expand Down Expand Up @@ -691,6 +692,7 @@ impl<BS: Blockstore> MockRuntime<BS> {
exit_code,
send_flags: SendFlags::default(),
gas_limit: None,
send_error: None,
})
}

Expand All @@ -706,6 +708,7 @@ impl<BS: Blockstore> MockRuntime<BS> {
send_flags: SendFlags,
send_return: Option<IpldBlock>,
exit_code: ExitCode,
send_error: Option<ErrorNumber>,
) {
self.expectations.borrow_mut().expect_sends.push_back(ExpectedMessage {
to,
Expand All @@ -716,6 +719,7 @@ impl<BS: Blockstore> MockRuntime<BS> {
value,
send_flags,
gas_limit,
send_error,
})
}

Expand Down Expand Up @@ -1179,6 +1183,10 @@ impl<BS: Blockstore> Runtime for MockRuntime<BS> {
expected_msg.value == value,
);

if let Some(e) = expected_msg.send_error {
return Err(e);
}

{
let mut balance = self.balance.borrow_mut();
if value > *balance {
Expand Down