neo3/neo_types/
tx_pool.rs

1use std::{collections::BTreeMap, fmt, str::FromStr};
2
3use primitive_types::U256;
4use serde::{
5	de::{self, Deserializer, Visitor},
6	Deserialize, Serialize,
7};
8
9use neo3::prelude::Address;
10
11/// Transaction summary as found in the Txpool Inspection property.
12#[derive(Debug, Clone, PartialEq, Eq)]
13pub struct TxPoolInspectSummary {
14	/// Recipient (None when contract creation)
15	pub to: Option<Address>,
16	/// Transferred value
17	pub value: U256,
18	/// Gas amount
19	pub gas: U256,
20}
21
22/// Visitor struct for TxpoolInspectSummary.
23struct TxPoolInspectSummaryVisitor;
24
25/// Walk through the deserializer to parse a txpool inspection summary into the
26/// `TxpoolInspectSummary` struct.
27impl<'de> Visitor<'de> for TxPoolInspectSummaryVisitor {
28	type Value = TxPoolInspectSummary;
29
30	fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
31		formatter.write_str("to: value wei + gasLimit gas × gas_price wei")
32	}
33
34	fn visit_string<E>(self, value: String) -> Result<Self::Value, E>
35	where
36		E: de::Error,
37	{
38		self.visit_str(&value)
39	}
40
41	fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
42	where
43		E: de::Error,
44	{
45		let addr_split: Vec<&str> = value.split(": ").collect();
46		if addr_split.len() != 2 {
47			return Err(de::Error::custom("invalid format for TxpoolInspectSummary: to"));
48		}
49		let value_split: Vec<&str> = addr_split[1].split(" wei + ").collect();
50		if value_split.len() != 2 {
51			return Err(de::Error::custom("invalid format for TxpoolInspectSummary: gasLimit"));
52		}
53		let gas_split: Vec<&str> = value_split[1].split(" gas × ").collect();
54		if gas_split.len() != 2 {
55			return Err(de::Error::custom("invalid format for TxpoolInspectSummary: gas"));
56		}
57
58		let addr = match addr_split[0] {
59			"" => None,
60			"0x" => None,
61			"contract creation" => None,
62			addr => {
63				Some(Address::from_str(addr.trim_start_matches("0x")).map_err(de::Error::custom)?)
64			},
65		};
66		let value = U256::from_dec_str(value_split[0]).map_err(de::Error::custom)?;
67		let gas = U256::from_dec_str(gas_split[0]).map_err(de::Error::custom)?;
68
69		Ok(TxPoolInspectSummary { to: addr, value, gas })
70	}
71}
72
73/// Implement the `Deserialize` trait for `TxpoolInspectSummary` struct.
74impl<'de> Deserialize<'de> for TxPoolInspectSummary {
75	fn deserialize<D>(deserializer: D) -> Result<TxPoolInspectSummary, D::Error>
76	where
77		D: Deserializer<'de>,
78	{
79		deserializer.deserialize_str(TxPoolInspectSummaryVisitor)
80	}
81}
82
83/// Implement the `Serialize` trait for `TxpoolInspectSummary` struct so that the
84/// format matches the one from geth.
85impl Serialize for TxPoolInspectSummary {
86	fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
87	where
88		S: serde::Serializer,
89	{
90		let formatted_to = if let Some(to) = self.to.clone() {
91			format!("{to:?}")
92		} else {
93			"contract creation".to_string()
94		};
95		let formatted = format!("{}: {} wei + {} gas", formatted_to, self.value, self.gas);
96		serializer.serialize_str(&formatted)
97	}
98}
99
100/// Transaction Pool Content
101///
102/// The content inspection property can be queried to list the exact details of all
103/// the transactions currently pending for inclusion in the next block(s), as well
104/// as the ones that are being scheduled for future execution only.
105///
106/// See [here](https://geth.neo.org/docs/rpc/ns-txpool#txpool_content) for more details
107#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)]
108pub struct TxpoolContent<TX> {
109	/// pending tx
110	pub pending: BTreeMap<Address, BTreeMap<String, TX>>,
111	/// queued tx
112	pub queued: BTreeMap<Address, BTreeMap<String, TX>>,
113}
114
115/// Transaction Pool Inspect
116///
117/// The inspect inspection property can be queried to list a textual summary
118/// of all the transactions currently pending for inclusion in the next block(s),
119/// as well as the ones that are being scheduled for future execution only.
120/// This is a method specifically tailored to developers to quickly see the
121/// transactions in the pool and find any potential issues.
122///
123/// See [here](https://geth.neo.org/docs/rpc/ns-txpool#txpool_inspect) for more details
124#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)]
125pub struct TxpoolInspect {
126	/// pending tx
127	pub pending: BTreeMap<Address, BTreeMap<String, TxPoolInspectSummary>>,
128	/// queued tx
129	pub queued: BTreeMap<Address, BTreeMap<String, TxPoolInspectSummary>>,
130}
131
132/// Transaction Pool Status
133///
134/// The status inspection property can be queried for the number of transactions
135/// currently pending for inclusion in the next block(s), as well as the ones that
136/// are being scheduled for future execution only.
137///
138/// See [here](https://geth.neo.org/docs/rpc/ns-txpool#txpool_status) for more details
139#[derive(Debug, Default, Clone, PartialEq, Eq, Deserialize, Serialize)]
140pub struct TxpoolStatus {
141	/// number of pending tx
142	pub pending: u64,
143	/// number of queued tx
144	pub queued: u64,
145}