forest/rpc/methods/
misc.rs1use std::collections::BTreeMap;
5
6use cid::Cid;
7use enumflags2::BitFlags;
8use fvm_ipld_blockstore::Blockstore;
9use schemars::JsonSchema;
10use serde::{Deserialize, Serialize};
11
12use crate::rpc::eth::CollectedEvent;
13use crate::rpc::eth::filter::{ParsedFilter, SkipEvent};
14use crate::{
15 blocks::TipsetKey,
16 lotus_json::{LotusJson, lotus_json_with_self},
17 rpc::{ApiPaths, Ctx, Permission, RpcMethod, ServerError, types::EventEntry},
18 shim::{address::Address, clock::ChainEpoch},
19};
20
21pub enum GetActorEventsRaw {}
22impl RpcMethod<1> for GetActorEventsRaw {
23 const NAME: &'static str = "Filecoin.GetActorEventsRaw";
24 const PARAM_NAMES: [&'static str; 1] = ["eventFilter"];
25 const API_PATHS: BitFlags<ApiPaths> = ApiPaths::all();
26 const PERMISSION: Permission = Permission::Read;
27 const DESCRIPTION: Option<&'static str> = Some(
28 "Returns all user-programmed and built-in actor events that match the given filter. Results may be limited by MaxFilterResults, MaxFilterHeightRange, and the node's available historical data.",
29 );
30
31 type Params = (Option<ActorEventFilter>,);
32 type Ok = Vec<ActorEvent>;
33 async fn handle(
34 ctx: Ctx<impl Blockstore + Send + Sync + 'static>,
35 (filter,): Self::Params,
36 ) -> Result<Self::Ok, ServerError> {
37 if let Some(filter) = filter {
38 let parsed_filter = ParsedFilter::from_actor_event_filter(
39 ctx.chain_store().heaviest_tipset().epoch(),
40 ctx.eth_event_handler.max_filter_height_range,
41 filter,
42 )?;
43 let events = ctx
44 .eth_event_handler
45 .get_events_for_parsed_filter(&ctx, &parsed_filter, SkipEvent::Never)
46 .await?;
47 Ok(events.into_iter().map(|ce| ce.into()).collect())
48 } else {
49 Ok(vec![])
50 }
51 }
52}
53
54#[derive(Clone, JsonSchema, Serialize, Deserialize)]
55#[serde(rename_all = "camelCase")]
56pub struct ActorEventFilter {
57 #[serde(default, skip_serializing_if = "Vec::is_empty")]
58 pub addresses: Vec<LotusJson<Address>>,
59 #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
60 pub fields: BTreeMap<String, Vec<ActorEventBlock>>,
61 #[serde(default, skip_serializing_if = "Option::is_none")]
62 pub from_height: Option<ChainEpoch>,
63 #[serde(default, skip_serializing_if = "Option::is_none")]
64 pub to_height: Option<ChainEpoch>,
65 #[serde(default, skip_serializing_if = "Option::is_none")]
66 pub tipset_key: Option<LotusJson<TipsetKey>>,
67}
68
69#[derive(Clone, JsonSchema, Serialize, Deserialize)]
70pub struct ActorEventBlock {
71 pub codec: u64,
72 pub value: LotusJson<Vec<u8>>,
73}
74
75#[derive(Debug, PartialEq, Clone, JsonSchema, Serialize, Deserialize)]
76#[serde(rename_all = "camelCase")]
77pub struct ActorEvent {
78 pub entries: Vec<EventEntry>,
79 pub emitter: LotusJson<Address>,
80 pub reverted: bool,
81 pub height: ChainEpoch,
82 pub tipset_key: LotusJson<TipsetKey>,
83 pub msg_cid: LotusJson<Cid>,
84}
85
86lotus_json_with_self! {
87 ActorEvent,
88 ActorEventFilter
89}
90
91impl From<CollectedEvent> for ActorEvent {
92 fn from(event: CollectedEvent) -> Self {
93 ActorEvent {
94 entries: event.entries,
95 emitter: LotusJson(event.emitter_addr),
96 reverted: event.reverted,
97 height: event.height,
98 tipset_key: LotusJson(event.tipset_key),
99 msg_cid: LotusJson(event.msg_cid),
100 }
101 }
102}