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}