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