client/rpc/types/cfx/pubsub.rs
1// Copyright 2015-2019 Parity Technologies (UK) Ltd.
2// This file is part of Parity Ethereum.
3
4// Parity Ethereum is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8
9// Parity Ethereum is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13
14// You should have received a copy of the GNU General Public License
15// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
16
17// Copyright 2019 Conflux Foundation. All rights reserved.
18// Conflux is free software and distributed under GNU General Public License.
19// See http://www.gnu.org/licenses/
20
21//! Pub-Sub types.
22
23use crate::rpc::types::{CfxRpcLogFilter, Header, Log};
24use cfx_types::{H256, U256};
25use serde::{de::Error, Deserialize, Deserializer, Serialize};
26use serde_json::{from_value, Value};
27
28/// Subscription result.
29#[allow(dead_code)]
30#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
31#[serde(untagged, rename_all = "camelCase")]
32// NOTE: rename_all does not apply to enum member fields
33// see: https://github.com/serde-rs/serde/issues/1061
34pub enum Result {
35 /// New block header.
36 Header(Header),
37
38 /// Log
39 Log(Log),
40
41 /// Transaction hash
42 TransactionHash(H256),
43
44 /// Epoch
45 #[serde(rename_all = "camelCase")]
46 Epoch {
47 epoch_number: U256,
48 epoch_hashes_ordered: Vec<H256>,
49 },
50
51 /// Chain reorg
52 #[serde(rename_all = "camelCase")]
53 ChainReorg { revert_to: U256 },
54}
55
56/// Subscription kind.
57#[derive(Debug, Deserialize, PartialEq, Eq, Hash, Clone)]
58#[serde(deny_unknown_fields)]
59#[serde(rename_all = "camelCase")]
60pub enum Kind {
61 /// New block headers subscription.
62 NewHeads,
63 /// Logs subscription.
64 Logs,
65 /// New Pending Transactions subscription.
66 NewPendingTransactions,
67 /// Node syncing status subscription.
68 Syncing,
69 /// Epoch
70 Epochs,
71}
72
73/// Subscription epoch.
74#[derive(Debug, Deserialize, PartialEq, Eq, Hash, Clone, Copy)]
75#[serde(deny_unknown_fields)]
76#[serde(rename_all = "snake_case")]
77pub enum SubscriptionEpoch {
78 /// Latest epoch available.
79 LatestMined,
80 /// Latest epoch executed.
81 LatestState,
82}
83
84/// Subscription kind.
85#[derive(Debug, PartialEq, Eq, Hash, Clone)]
86pub enum Params {
87 /// No parameters passed.
88 None,
89 /// Log parameters.
90 Logs(CfxRpcLogFilter),
91 /// Epoch parameters.
92 Epochs(SubscriptionEpoch),
93}
94
95impl Default for Params {
96 fn default() -> Self { Params::None }
97}
98
99impl<'a> Deserialize<'a> for Params {
100 fn deserialize<D>(
101 deserializer: D,
102 ) -> ::std::result::Result<Params, D::Error>
103 where D: Deserializer<'a> {
104 let v: Value = Deserialize::deserialize(deserializer)?;
105
106 if v.is_null() {
107 return Ok(Params::None);
108 }
109
110 // try to interpret as a log filter
111 if let Ok(v) = from_value(v.clone()).map(Params::Logs) {
112 return Ok(v);
113 }
114
115 // otherwise, interpret as epoch
116 from_value(v).map(Params::Epochs).map_err(|e| {
117 D::Error::custom(format!("Invalid Pub-Sub parameters: {}", e))
118 })
119 }
120}