Skip to content

Commit acad70a

Browse files
committed
add an integration test to simulate fatal errors.
And peep into backtraces.
1 parent c2bf65f commit acad70a

File tree

5 files changed

+218
-31
lines changed

5 files changed

+218
-31
lines changed

fvm/src/machine/default.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,9 @@ where
113113
// This interface works for now because we know all actor CIDs
114114
// ahead of time, but with user-supplied code, we won't have that
115115
// guarantee.
116+
// Skip preloading all builtin actors when testing. This results in JIT
117+
// bytecode to machine code compilation, and leads to faster tests.
118+
#[cfg(not(feature = "testing"))]
116119
engine.preload(state_tree.store(), builtin_actors.left_values())?;
117120

118121
Ok(DefaultMachine {

testing/integration/examples/integration.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use fvm::executor::{ApplyKind, Executor};
22
use fvm_integration_tests::tester::{Account, Tester};
3+
use fvm_ipld_blockstore::MemoryBlockstore;
34
use fvm_ipld_encoding::tuple::*;
45
use fvm_shared::address::Address;
56
use fvm_shared::bigint::BigInt;
@@ -25,7 +26,12 @@ struct State {
2526

2627
pub fn main() {
2728
// Instantiate tester
28-
let mut tester = Tester::new(NetworkVersion::V15, StateTreeVersion::V4).unwrap();
29+
let mut tester = Tester::new(
30+
NetworkVersion::V15,
31+
StateTreeVersion::V4,
32+
&MemoryBlockstore::default(),
33+
)
34+
.unwrap();
2935

3036
let sender: [Account; 1] = tester.create_accounts().unwrap();
3137

testing/integration/src/builtin.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use cid::Cid;
55
use futures::executor::block_on;
66
use fvm::state_tree::{ActorState, StateTree};
77
use fvm::{init_actor, system_actor};
8-
use fvm_ipld_blockstore::{Blockstore, MemoryBlockstore};
8+
use fvm_ipld_blockstore::Blockstore;
99
use fvm_ipld_car::load_car;
1010
use fvm_ipld_encoding::CborStore;
1111
use fvm_shared::actor::builtin::{load_manifest, Type};
@@ -24,7 +24,7 @@ const BUNDLES: [(NetworkVersion, &[u8]); 3] = [
2424

2525
// Import built-in actors
2626
pub fn import_builtin_actors(
27-
blockstore: &MemoryBlockstore,
27+
blockstore: &impl Blockstore,
2828
) -> Result<BTreeMap<NetworkVersion, Cid>> {
2929
BUNDLES
3030
.into_iter()
@@ -40,7 +40,7 @@ pub fn import_builtin_actors(
4040

4141
// Retrieve system, init and accounts actors code CID
4242
pub fn fetch_builtin_code_cid(
43-
blockstore: &MemoryBlockstore,
43+
blockstore: &impl Blockstore,
4444
builtin_actors: &Cid,
4545
ver: u32,
4646
) -> Result<(Cid, Cid, Cid)> {

testing/integration/src/tester.rs

Lines changed: 38 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use fvm::executor::DefaultExecutor;
55
use fvm::machine::{DefaultMachine, Engine, Machine, NetworkConfig};
66
use fvm::state_tree::{ActorState, StateTree};
77
use fvm::{init_actor, system_actor, DefaultKernel};
8-
use fvm_ipld_blockstore::{Block, Blockstore, MemoryBlockstore};
8+
use fvm_ipld_blockstore::{Block, Blockstore};
99
use fvm_ipld_encoding::{ser, CborStore};
1010
use fvm_ipld_hamt::Hamt;
1111
use fvm_shared::address::Address;
@@ -24,15 +24,14 @@ use crate::error::Error::{FailedToFlushTree, NoManifestInformation, NoRootCid};
2424

2525
const DEFAULT_BASE_FEE: u64 = 100;
2626

27-
trait Store: Blockstore + Sized {}
27+
pub trait Store: Blockstore + Sized + 'static {}
2828

29-
pub type IntegrationExecutor = DefaultExecutor<
30-
DefaultKernel<DefaultCallManager<DefaultMachine<MemoryBlockstore, DummyExterns>>>,
31-
>;
29+
pub type IntegrationExecutor<B> =
30+
DefaultExecutor<DefaultKernel<DefaultCallManager<DefaultMachine<B, DummyExterns>>>>;
3231

3332
pub type Account = (ActorID, Address);
3433

35-
pub struct Tester {
34+
pub struct Tester<B: Blockstore + 'static> {
3635
// Network version used in the test
3736
nv: NetworkVersion,
3837
// Builtin actors root Cid used in the Machine
@@ -42,16 +41,16 @@ pub struct Tester {
4241
// Custom code cid deployed by developer
4342
code_cids: Vec<Cid>,
4443
// Executor used to interact with deployed actors.
45-
pub executor: Option<IntegrationExecutor>,
44+
pub executor: Option<IntegrationExecutor<B>>,
4645
// State tree constructed before instantiating the Machine
47-
pub state_tree: StateTree<MemoryBlockstore>,
46+
pub state_tree: Option<StateTree<B>>,
4847
}
4948

50-
impl Tester {
51-
pub fn new(nv: NetworkVersion, stv: StateTreeVersion) -> Result<Self> {
52-
// Initialize blockstore
53-
let blockstore = MemoryBlockstore::default();
54-
49+
impl<B> Tester<B>
50+
where
51+
B: Blockstore,
52+
{
53+
pub fn new(nv: NetworkVersion, stv: StateTreeVersion, blockstore: B) -> Result<Self> {
5554
// Load the builtin actors bundles into the blockstore.
5655
let nv_actors = import_builtin_actors(&blockstore)?;
5756

@@ -92,21 +91,29 @@ impl Tester {
9291
builtin_actors,
9392
executor: None,
9493
code_cids: vec![],
95-
state_tree,
94+
state_tree: Some(state_tree),
9695
accounts_code_cid,
9796
})
9897
}
9998

10099
/// Creates new accounts in the testing context
101100
pub fn create_accounts<const N: usize>(&mut self) -> Result<[Account; N]> {
102101
// Create accounts.
103-
put_secp256k1_accounts(&mut self.state_tree, self.accounts_code_cid)
102+
put_secp256k1_accounts(
103+
&mut self.state_tree.as_mut().unwrap(),
104+
self.accounts_code_cid,
105+
)
104106
}
105107

106108
/// Set a new state in the state tree
107109
pub fn set_state<S: ser::Serialize>(&mut self, state: &S) -> Result<Cid> {
108110
// Put state in tree
109-
let state_cid = self.state_tree.store().put_cbor(state, Code::Blake2b256)?;
111+
let state_cid = self
112+
.state_tree
113+
.as_mut()
114+
.unwrap()
115+
.store()
116+
.put_cbor(state, Code::Blake2b256)?;
110117

111118
Ok(state_cid)
112119
}
@@ -121,11 +128,13 @@ impl Tester {
121128
) -> Result<()> {
122129
// Register actor address
123130
self.state_tree
131+
.as_mut()
132+
.unwrap()
124133
.register_new_address(&actor_address)
125134
.unwrap();
126135

127136
// Put the WASM code into the blockstore.
128-
let code_cid = put_wasm_code(self.state_tree.store(), wasm_bin)?;
137+
let code_cid = put_wasm_code(self.state_tree.as_mut().unwrap().store(), wasm_bin)?;
129138

130139
// Add code cid to list of deployed contract
131140
self.code_cids.push(code_cid);
@@ -135,6 +144,8 @@ impl Tester {
135144

136145
// Create actor
137146
self.state_tree
147+
.as_mut()
148+
.unwrap()
138149
.set_actor(&actor_address, actor_state)
139150
.map_err(anyhow::Error::from)?;
140151

@@ -143,14 +154,17 @@ impl Tester {
143154

144155
/// Sets the Machine and the Executor in our Tester structure.
145156
pub fn instantiate_machine(&mut self) -> Result<()> {
146-
// First flush tree and consume it
147-
let state_root = self
148-
.state_tree
157+
// Take the state tree and leave None behind.
158+
let mut state_tree = self.state_tree.take().unwrap();
159+
160+
// Calculate the state root.
161+
let state_root = state_tree
149162
.flush()
150163
.map_err(anyhow::Error::from)
151164
.context(FailedToFlushTree)?;
152165

153-
let blockstore = self.state_tree.store();
166+
// Consume the state tree and take the blockstore.
167+
let blockstore = state_tree.into_store();
154168

155169
let mut nc = NetworkConfig::new(self.nv);
156170
nc.override_actors(self.builtin_actors);
@@ -161,7 +175,7 @@ impl Tester {
161175
let machine = DefaultMachine::new(
162176
&Engine::new_default((&mc.network.clone()).into())?,
163177
&mc,
164-
blockstore.clone(),
178+
blockstore,
165179
dummy::DummyExterns,
166180
)?;
167181

@@ -180,7 +194,7 @@ impl Tester {
180194
if self.executor.is_some() {
181195
self.executor.as_ref().unwrap().blockstore()
182196
} else {
183-
self.state_tree.store()
197+
self.state_tree.as_ref().unwrap().store()
184198
}
185199
}
186200
}
@@ -224,7 +238,7 @@ fn put_secp256k1_accounts<const N: usize>(
224238
}
225239

226240
/// Inserts the WASM code for the actor into the blockstore.
227-
fn put_wasm_code(blockstore: &MemoryBlockstore, wasm_binary: &[u8]) -> Result<Cid> {
241+
fn put_wasm_code(blockstore: &impl Blockstore, wasm_binary: &[u8]) -> Result<Cid> {
228242
let cid = blockstore.put(
229243
Code::Blake2b256,
230244
&Block {

0 commit comments

Comments
 (0)