1use fil_actors_runtime::runtime::{ActorCode, Runtime};
5use fil_actors_runtime::{actor_error, cbor, ActorError, SYSTEM_ACTOR_ADDR};
6use fvm_ipld_blockstore::Blockstore;
7use fvm_ipld_encoding::tuple::*;
8use fvm_ipld_encoding::RawBytes;
9use fvm_shared::econ::TokenAmount;
10
11use fvm_shared::{MethodNum, METHOD_CONSTRUCTOR};
12use num_derive::FromPrimitive;
13use num_traits::{FromPrimitive, Zero};
14
15pub use self::state::{Entry, State};
16
17mod state;
18pub mod testing;
19
20#[cfg(feature = "fil-actor")]
21fil_actors_runtime::wasm_trampoline!(Actor);
22
23#[derive(FromPrimitive)]
27#[repr(u64)]
28pub enum Method {
29 Constructor = METHOD_CONSTRUCTOR,
30 EpochTick = 2,
31}
32
33#[derive(Default, Debug, Serialize_tuple, Deserialize_tuple)]
36pub struct ConstructorParams {
37 pub entries: Vec<Entry>,
39}
40
41pub struct Actor;
43impl Actor {
44 fn constructor<BS, RT>(rt: &mut RT, params: ConstructorParams) -> Result<(), ActorError>
46 where
47 BS: Blockstore,
48 RT: Runtime<BS>,
49 {
50 rt.validate_immediate_caller_is(std::iter::once(&SYSTEM_ACTOR_ADDR))?;
51 rt.create(&State { entries: params.entries })?;
52 Ok(())
53 }
54 fn epoch_tick<BS, RT>(rt: &mut RT) -> Result<(), ActorError>
58 where
59 BS: Blockstore,
60 RT: Runtime<BS>,
61 {
62 rt.validate_immediate_caller_is(std::iter::once(&SYSTEM_ACTOR_ADDR))?;
63
64 let st: State = rt.state()?;
65 for entry in st.entries {
66 let res = rt.send(
68 &entry.receiver,
69 entry.method_num,
70 RawBytes::default(),
71 TokenAmount::zero(),
72 );
73 if let Err(e) = res {
74 log::error!(
75 "cron failed to send entry to {}, send error code {}",
76 entry.receiver,
77 e
78 );
79 }
80 }
81 Ok(())
82 }
83}
84
85impl ActorCode for Actor {
86 fn invoke_method<BS, RT>(
87 rt: &mut RT,
88 method: MethodNum,
89 params: &RawBytes,
90 ) -> Result<RawBytes, ActorError>
91 where
92 BS: Blockstore,
93 RT: Runtime<BS>,
94 {
95 match FromPrimitive::from_u64(method) {
96 Some(Method::Constructor) => {
97 Self::constructor(rt, cbor::deserialize_params(params)?)?;
98 Ok(RawBytes::default())
99 }
100 Some(Method::EpochTick) => {
101 Self::epoch_tick(rt)?;
102 Ok(RawBytes::default())
103 }
104 None => Err(actor_error!(unhandled_message; "Invalid method")),
105 }
106 }
107}