Skip to content

Commit 6967a23

Browse files
authored
test: switch from ethers to alloy (#1602)
* test: switch from ethers to alloy Alloy is maintained, ethers is not. This lets us get rid of some outdated dependencies as well. fixes #1601 * remove std feature for alloy We don't actually use it.
1 parent fd6cb22 commit 6967a23

File tree

8 files changed

+249
-2217
lines changed

8 files changed

+249
-2217
lines changed

Cargo.lock

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

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ blake2b_simd = "1.0"
109109
sha2 = "0.10"
110110

111111
# EVM
112-
ethers = { version = "2.0.9", features = ["abigen"], default-features = false }
112+
alloy-core = { version = "0.8.19", default-features = false, features = ["sol-types"] }
113113
uint = { version = "0.9.3", default-features = false }
114114
etk-asm = "^0.3.0"
115115
rlp = { version = "0.5.1", default-features = false }

actors/evm/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ hex = { workspace = true, features = ["serde"] }
3939
lazy_static = { workspace = true }
4040
fil_actors_runtime = { workspace = true, features = ["test_utils", "sector-default"] }
4141
etk-asm = { workspace = true }
42-
ethers = { workspace = true }
42+
alloy-core = { workspace = true }
4343
serde_json = { workspace = true }
4444
rand = { workspace = true }
4545
once_cell = { workspace = true }

actors/evm/tests/call.rs

Lines changed: 43 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
11
mod asm;
22

33
use std::fmt::Debug;
4-
use std::sync::Arc;
54

6-
use ethers::abi::Detokenize;
7-
use ethers::prelude::builders::ContractCall;
8-
use ethers::prelude::*;
9-
use ethers::providers::{MockProvider, Provider};
10-
use ethers::types::Bytes;
5+
use alloy_core::primitives::{Bytes, Uint};
6+
use alloy_core::sol;
7+
use alloy_core::sol_types::SolCall;
118
use evm::{Method, EVM_CONTRACT_REVERTED};
129
use fil_actor_evm as evm;
1310
use fil_actors_evm_shared::address::EthAddress;
@@ -21,8 +18,7 @@ use fvm_shared::bigint::Zero;
2118
use fvm_shared::econ::TokenAmount;
2219
use fvm_shared::error::{ErrorNumber, ExitCode};
2320
use fvm_shared::sys::SendFlags;
24-
use fvm_shared::{ActorID, MethodNum};
25-
use once_cell::sync::Lazy;
21+
use fvm_shared::MethodNum;
2622

2723
mod util;
2824

@@ -432,21 +428,7 @@ fn test_callactor_revert() {
432428
}
433429

434430
// Much taken from tests/env.rs
435-
abigen!(CallActorPrecompile, "./tests/contracts/CallActorPrecompile.abi");
436-
437-
const OWNER_ID: ActorID = 1001;
438-
const _OWNER: Address = Address::new_id(OWNER_ID);
439-
static CONTRACT: Lazy<CallActorPrecompile<Provider<MockProvider>>> = Lazy::new(|| {
440-
// The owner of the contract is expected to be the 160 bit hash used on Ethereum.
441-
// We're not going to use it during the tests.
442-
let address = EthAddress::from_id(OWNER_ID);
443-
let address = ethers::core::types::Address::from_slice(address.as_ref());
444-
// A dummy client that we don't intend to use to call the contract or send transactions.
445-
let (client, _mock) = Provider::mocked();
446-
CallActorPrecompile::new(address, Arc::new(client))
447-
});
448-
449-
pub type TestContractCall<R> = ContractCall<Provider<MockProvider>, R>;
431+
sol!("./tests/contracts/CallActorPrecompile.sol");
450432

451433
#[test]
452434
fn test_callactor_restrict() {
@@ -1031,18 +1013,24 @@ fn make_raw_params(bytes: Vec<u8>) -> Option<IpldBlock> {
10311013
Some(IpldBlock { codec: IPLD_RAW, data: bytes })
10321014
}
10331015

1016+
const CALL_ACTOR_PRECOMPILE_HEX: &str = include_str!("contracts/CallActorPrecompile.hex");
1017+
10341018
#[test]
10351019
fn call_actor_solidity() {
1036-
// solidity
1037-
let contract_hex = include_str!("contracts/CallActorPrecompile.hex");
10381020
// let mut contract_rt = new_call_actor_contract();
10391021
let contract_address = EthAddress(util::CONTRACT_ADDRESS);
1040-
let mut tester = ContractTester::new(contract_address, 111, contract_hex);
1022+
let mut tester = ContractTester::new(contract_address, 111, CALL_ACTOR_PRECOMPILE_HEX);
10411023

10421024
// call_actor_id
10431025
{
1044-
let params =
1045-
CONTRACT.call_actor_id(0, ethers::types::U256::zero(), 0, 0, Bytes::default(), 101);
1026+
let params = CallActorPrecompile::call_actor_idCall {
1027+
method: 0,
1028+
value: Uint::from(0),
1029+
flags: 0,
1030+
codec: 0,
1031+
params: Bytes::default(),
1032+
id: 101,
1033+
};
10461034

10471035
let expected_return = vec![0xff, 0xfe];
10481036
tester.rt.expect_send(
@@ -1057,35 +1045,26 @@ fn call_actor_solidity() {
10571045
None,
10581046
);
10591047

1060-
let (success, exit, codec, ret_val): (bool, ethers::types::I256, u64, Bytes) =
1061-
tester.call(params);
1048+
let (success, exit, codec, ret_val) = tester.call(params).into();
10621049

10631050
assert!(success);
1064-
assert_eq!(exit, I256::from(0));
1051+
assert!(exit.is_zero());
10651052
assert_eq!(codec, 0);
10661053
assert_eq!(&ret_val, &expected_return, "got {}", hex::encode(&ret_val));
1067-
}
1068-
tester.rt.reset();
1069-
// call_actor
1070-
{
1071-
log::warn!("new test");
1072-
// EVM actor
1073-
let evm_target = 10101;
1074-
let evm_del = EthAddress(util::CONTRACT_ADDRESS).into();
1075-
tester.rt.set_delegated_address(evm_target, evm_del);
10761054

10771055
let to_address = {
10781056
let subaddr = hex_literal::hex!("b0ba000000000000000000000000000000000000");
10791057
Address::new_delegated(EAM_ACTOR_ID, &subaddr).unwrap()
10801058
};
1081-
let params = CONTRACT.call_actor_address(
1082-
0,
1083-
ethers::types::U256::zero(),
1084-
0,
1085-
0,
1086-
Bytes::default(),
1087-
to_address.to_bytes().into(),
1088-
);
1059+
1060+
let params = CallActorPrecompile::call_actor_addressCall {
1061+
method: 0,
1062+
value: Uint::from(0),
1063+
flags: 0,
1064+
codec: 0,
1065+
params: Bytes::default(),
1066+
filAddress: to_address.to_bytes().into(),
1067+
};
10891068

10901069
let expected_return = vec![0xff, 0xfe];
10911070
tester.rt.expect_send(
@@ -1100,28 +1079,31 @@ fn call_actor_solidity() {
11001079
None,
11011080
);
11021081

1103-
let (success, exit, codec, ret_val): (bool, ethers::types::I256, u64, Bytes) =
1104-
tester.call(params);
1082+
let (success, exit, codec, ret_val) = tester.call(params).into();
11051083

11061084
assert!(success);
1107-
assert_eq!(exit, I256::from(0));
1085+
assert!(exit.is_zero());
11081086
assert_eq!(codec, 0);
11091087
assert_eq!(&ret_val, &expected_return, "got {}", hex::encode(&ret_val));
11101088
}
11111089
}
11121090

11131091
#[test]
11141092
fn call_actor_send_solidity() {
1115-
// solidity
1116-
let contract_hex = include_str!("contracts/CallActorPrecompile.hex");
11171093
// let mut contract_rt = new_call_actor_contract();
11181094
let contract_address = EthAddress(util::CONTRACT_ADDRESS);
1119-
let mut tester = ContractTester::new(contract_address, 111, contract_hex);
1095+
let mut tester = ContractTester::new(contract_address, 111, CALL_ACTOR_PRECOMPILE_HEX);
11201096

11211097
// send 1 atto Fil (this should be a full integration tests rly)
11221098
{
1123-
let params =
1124-
CONTRACT.call_actor_id(0, ethers::types::U256::from(1), 0, 0, Bytes::default(), 101);
1099+
let params = CallActorPrecompile::call_actor_idCall {
1100+
method: 0,
1101+
value: Uint::from(1),
1102+
flags: 0,
1103+
codec: 0,
1104+
params: Bytes::default(),
1105+
id: 101,
1106+
};
11251107

11261108
tester.rt.add_id_address(
11271109
Address::new_delegated(12345, b"foobarboxy").unwrap(),
@@ -1143,11 +1125,10 @@ fn call_actor_send_solidity() {
11431125
None,
11441126
);
11451127

1146-
let (success, exit, codec, ret_val): (bool, ethers::types::I256, u64, Bytes) =
1147-
tester.call(params);
1128+
let (success, exit, codec, ret_val) = tester.call(params).into();
11481129

11491130
assert!(success);
1150-
assert_eq!(exit, I256::from(0));
1131+
assert!(exit.is_zero());
11511132
assert_eq!(codec, 0);
11521133
assert_eq!(&ret_val, &expected_return, "got {}", hex::encode(&ret_val));
11531134
assert_eq!(tester.rt.get_balance(), TokenAmount::from_atto(99));
@@ -1191,8 +1172,8 @@ impl ContractTester {
11911172
Self { rt, _address: addr }
11921173
}
11931174

1194-
fn call<Returns: Detokenize>(&mut self, call: TestContractCall<Returns>) -> Returns {
1195-
let input = call.calldata().expect("Should have calldata.").to_vec();
1175+
pub fn call<C: SolCall>(&mut self, call: C) -> C::Return {
1176+
let input = call.abi_encode();
11961177
let input =
11971178
IpldBlock::serialize_cbor(&BytesSer(&input)).expect("failed to serialize input data");
11981179

@@ -1208,6 +1189,6 @@ impl ContractTester {
12081189
.deserialize()
12091190
.unwrap();
12101191

1211-
decode_function_data(&call.function, result, false).unwrap()
1192+
C::abi_decode_returns(&result, true).unwrap()
12121193
}
12131194
}

actors/evm/tests/env.rs

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
1-
use ethers::{
2-
abi::Detokenize,
3-
prelude::{builders::ContractCall, decode_function_data},
4-
providers::{MockProvider, Provider},
5-
};
1+
use alloy_core::sol_types::SolCall;
62

73
use fil_actor_evm as evm;
84
use fil_actors_evm_shared::address::EthAddress;
@@ -15,9 +11,6 @@ use fvm_ipld_encoding::ipld_block::IpldBlock;
1511
use fvm_ipld_encoding::{BytesDe, BytesSer};
1612
use fvm_shared::address::Address;
1713

18-
/// Alias for a call we will never send to the blockchain.
19-
pub type TestContractCall<R> = ContractCall<Provider<MockProvider>, R>;
20-
2114
pub struct TestEnv {
2215
evm_address: Address,
2316
pub runtime: MockRuntime,
@@ -75,11 +68,8 @@ impl TestEnv {
7568
self.runtime.verify();
7669
}
7770

78-
/// Take a function that calls an ABI method to return a `ContractCall`.
79-
/// Then, instead of calling the contract on-chain, run it through our
80-
/// EVM interpreter in the test runtime. Finally parse the results.
81-
pub fn call<R: Detokenize>(&mut self, call: TestContractCall<R>) -> R {
82-
let input = call.calldata().expect("Should have calldata.");
71+
pub fn call<C: SolCall>(&mut self, call: C) -> C::Return {
72+
let input = call.abi_encode();
8373
let input =
8474
IpldBlock::serialize_cbor(&BytesSer(&input)).expect("failed to serialize input data");
8575
self.runtime.expect_validate_caller_any();
@@ -92,6 +82,6 @@ impl TestEnv {
9282
.deserialize()
9383
.unwrap();
9484

95-
decode_function_data(&call.function, result, false).unwrap()
85+
C::abi_decode_returns(&result, true).unwrap()
9686
}
9787
}

deny.toml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
[advisories]
2-
ignore = [
3-
"RUSTSEC-2024-0384", # instant is unmaintained, required by ethers
4-
]
2+
ignore = []
53

64
[licenses]
75
allow = [

integration_tests/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ anyhow = { workspace = true }
3535
bimap = { workspace = true }
3636
blake2b_simd = { workspace = true }
3737
cid = { workspace = true }
38-
ethers = { workspace = true }
38+
alloy-core = { workspace = true }
3939
frc42_dispatch = { workspace = true }
4040
frc46_token = { workspace = true }
4141
fvm_actor_utils = { workspace = true }

0 commit comments

Comments
 (0)