mod bundles;
use bundles::*;
use fvm::executor::{ApplyKind, Executor};
use fvm::machine::Machine;
use fvm_integration_tests::dummy::DummyExterns;
use fvm_integration_tests::tester::IntegrationExecutor;
use fvm_ipld_blockstore::{Blockstore, MemoryBlockstore};
use fvm_ipld_encoding::{IPLD_RAW, to_vec};
use fvm_shared::address::Address;
use fvm_shared::econ::TokenAmount;
use fvm_shared::error::ExitCode;
use fvm_shared::event::{Entry, Flags, StampedEvent};
use fvm_shared::message::Message;
use fvm_shared::state::StateTreeVersion;
use fvm_shared::version::NetworkVersion;
use fvm_test_actors::wasm_bin::EVENTS_ACTOR_BINARY;
use num_traits::Zero;
#[test]
fn events_test() {
let (mut executor, sender_address, actor_address) = setup();
let message = Message {
from: sender_address,
to: actor_address,
gas_limit: 1000000000,
method_num: 2,
sequence: 0,
..Message::default()
};
let res = executor
.execute_message(message.clone(), ApplyKind::Explicit, 100)
.unwrap();
assert!(
res.msg_receipt.exit_code.is_success(),
"{:?}",
res.failure_info
);
let gas_used = res.msg_receipt.gas_used;
let actor_id = actor_address.id().unwrap();
assert_eq!(
&res.events,
&[
StampedEvent {
emitter: actor_id,
event: vec![Entry {
flags: Flags::all(),
key: "foo".to_owned(),
codec: IPLD_RAW,
value: "abc".into(),
},]
.into(),
},
StampedEvent {
emitter: actor_id,
event: vec![
Entry {
flags: Flags::all(),
key: "bar".to_owned(),
codec: IPLD_RAW,
value: "def".into(),
},
Entry {
flags: Flags::FLAG_INDEXED_KEY | Flags::FLAG_INDEXED_VALUE,
key: "👱".to_string(),
codec: IPLD_RAW,
value: "123456789 abcdefg 123456789".into(),
},
]
.into(),
},
]
);
assert!(res.msg_receipt.events_root.is_some());
assert!(
!executor
.blockstore()
.has(&res.msg_receipt.events_root.unwrap())
.unwrap()
);
let message = Message {
method_num: 3,
sequence: 1,
..message
};
let res = executor
.execute_message(message.clone(), ApplyKind::Explicit, 100)
.unwrap();
assert_eq!(ExitCode::OK, res.msg_receipt.exit_code);
assert!(res.msg_receipt.events_root.is_none());
let counter: u64 = 10;
let message = Message {
method_num: 4,
sequence: 2,
params: to_vec(&counter).unwrap().into(),
..message
};
let res = executor
.execute_message(message.clone(), ApplyKind::Explicit, 100)
.unwrap();
assert_eq!(ExitCode::OK, res.msg_receipt.exit_code);
assert_eq!(20, res.events.len());
let message = Message {
method_num: 5,
sequence: 3,
params: to_vec(&counter).unwrap().into(),
..message
};
let res = executor
.execute_message(message.clone(), ApplyKind::Explicit, 100)
.unwrap();
assert_eq!(ExitCode::OK, res.msg_receipt.exit_code);
assert_eq!(10, res.events.len());
let message = Message {
method_num: 2,
sequence: 4,
gas_limit: gas_used - 1,
..message
};
let res = executor
.execute_message(message, ApplyKind::Explicit, 100)
.unwrap();
assert_eq!(ExitCode::SYS_OUT_OF_GAS, res.msg_receipt.exit_code);
assert!(res.msg_receipt.events_root.is_none());
assert_eq!(0, res.events.len());
}
fn setup() -> (
IntegrationExecutor<MemoryBlockstore, DummyExterns>,
Address,
Address,
) {
let mut tester = new_tester(
NetworkVersion::V21,
StateTreeVersion::V5,
MemoryBlockstore::default(),
)
.unwrap();
let [(_sender_id, sender)] = tester.create_accounts().unwrap();
let wasm_bin = EVENTS_ACTOR_BINARY;
let actor_state = [(); 0];
let state_cid = tester.set_state(&actor_state).unwrap();
let actor = Address::new_id(10000);
tester
.set_actor_from_bin(wasm_bin, state_cid, actor, TokenAmount::zero())
.unwrap();
tester.instantiate_machine(DummyExterns).unwrap();
let executor = tester.executor.unwrap();
(executor, sender, actor)
}