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 _: &http::Extensions,
37 ) -> Result<Self::Ok, ServerError> {
38 if let Some(filter) = filter {
39 let parsed_filter = ParsedFilter::from_actor_event_filter(
40 ctx.chain_store().heaviest_tipset().epoch(),
41 ctx.eth_event_handler.max_filter_height_range,
42 filter,
43 )?;
44 let events = ctx
45 .eth_event_handler
46 .get_events_for_parsed_filter(&ctx, &parsed_filter, SkipEvent::Never)
47 .await?;
48 Ok(events.into_iter().map(|ce| ce.into()).collect())
49 } else {
50 Ok(vec![])
51 }
52 }
53}
54
55#[derive(Clone, JsonSchema, Serialize, Deserialize)]
56#[serde(rename_all = "camelCase")]
57pub struct ActorEventFilter {
58 #[serde(default, skip_serializing_if = "Vec::is_empty")]
59 pub addresses: Vec<LotusJson<Address>>,
60 #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
61 pub fields: BTreeMap<String, Vec<ActorEventBlock>>,
62 #[serde(default, skip_serializing_if = "Option::is_none")]
63 pub from_height: Option<ChainEpoch>,
64 #[serde(default, skip_serializing_if = "Option::is_none")]
65 pub to_height: Option<ChainEpoch>,
66 #[serde(default, skip_serializing_if = "Option::is_none")]
67 pub tipset_key: Option<LotusJson<TipsetKey>>,
68}
69
70#[derive(Clone, JsonSchema, Serialize, Deserialize)]
71pub struct ActorEventBlock {
72 pub codec: u64,
73 pub value: LotusJson<Vec<u8>>,
74}
75
76#[derive(Debug, PartialEq, Clone, JsonSchema, Serialize, Deserialize)]
77#[serde(rename_all = "camelCase")]
78pub struct ActorEvent {
79 pub entries: Vec<EventEntry>,
80 pub emitter: LotusJson<Address>,
81 pub reverted: bool,
82 pub height: ChainEpoch,
83 pub tipset_key: LotusJson<TipsetKey>,
84 pub msg_cid: LotusJson<Cid>,
85}
86
87lotus_json_with_self! {
88 ActorEvent,
89 ActorEventFilter
90}
91
92impl From<CollectedEvent> for ActorEvent {
93 fn from(event: CollectedEvent) -> Self {
94 ActorEvent {
95 entries: event.entries,
96 emitter: LotusJson(event.emitter_addr),
97 reverted: event.reverted,
98 height: event.height,
99 tipset_key: LotusJson(event.tipset_key),
100 msg_cid: LotusJson(event.msg_cid),
101 }
102 }
103}