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		let value = U256::from_dec_str(value_split[0]).map_err(de::Error::custom)?;
66		let gas = U256::from_dec_str(gas_split[0]).map_err(de::Error::custom)?;
67
68		Ok(TxPoolInspectSummary { to: addr, value, gas })
69	}
70}
71
72/// Implement the `Deserialize` trait for `TxpoolInspectSummary` struct.
73impl<'de> Deserialize<'de> for TxPoolInspectSummary {
74	fn deserialize<D>(deserializer: D) -> Result<TxPoolInspectSummary, D::Error>
75	where
76		D: Deserializer<'de>,
77	{
78		deserializer.deserialize_str(TxPoolInspectSummaryVisitor)
79	}
80}
81
82/// Implement the `Serialize` trait for `TxpoolInspectSummary` struct so that the
83/// format matches the one from geth.
84impl Serialize for TxPoolInspectSummary {
85	fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
86	where
87		S: serde::Serializer,
88	{
89		let formatted_to = if let Some(to) = self.to.clone() {
90			format!("{to:?}")
91		} else {
92			"contract creation".to_string()
93		};
94		let formatted = format!("{}: {} wei + {} gas", formatted_to, self.value, self.gas);
95		serializer.serialize_str(&formatted)
96	}
97}
98
99/// Transaction Pool Content
100///
101/// The content inspection property can be queried to list the exact details of all
102/// the transactions currently pending for inclusion in the next block(s), as well
103/// as the ones that are being scheduled for future execution only.
104///
105/// See [here](https://geth.neo.org/docs/rpc/ns-txpool#txpool_content) for more details
106#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)]
107pub struct TxpoolContent<TX> {
108	/// pending tx
109	pub pending: BTreeMap<Address, BTreeMap<String, TX>>,
110	/// queued tx
111	pub queued: BTreeMap<Address, BTreeMap<String, TX>>,
112}
113
114/// Transaction Pool Inspect
115///
116/// The inspect inspection property can be queried to list a textual summary
117/// of all the transactions currently pending for inclusion in the next block(s),
118/// as well as the ones that are being scheduled for future execution only.
119/// This is a method specifically tailored to developers to quickly see the
120/// transactions in the pool and find any potential issues.
121///
122/// See [here](https://geth.neo.org/docs/rpc/ns-txpool#txpool_inspect) for more details
123#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)]
124pub struct TxpoolInspect {
125	/// pending tx
126	pub pending: BTreeMap<Address, BTreeMap<String, TxPoolInspectSummary>>,
127	/// queued tx
128	pub queued: BTreeMap<Address, BTreeMap<String, TxPoolInspectSummary>>,
129}
130
131/// Transaction Pool Status
132///
133/// The status inspection property can be queried for the number of transactions
134/// currently pending for inclusion in the next block(s), as well as the ones that
135/// are being scheduled for future execution only.
136///
137/// See [here](https://geth.neo.org/docs/rpc/ns-txpool#txpool_status) for more details
138#[derive(Debug, Default, Clone, PartialEq, Eq, Deserialize, Serialize)]
139pub struct TxpoolStatus {
140	/// number of pending tx
141	pub pending: u64,
142	/// number of queued tx
143	pub queued: u64,
144}