sc_rpc_spec_v2/transaction/
error.rs1use crate::transaction::event::{TransactionError, TransactionEvent};
24use jsonrpsee::types::error::ErrorObject;
25use sc_transaction_pool_api::error::Error as PoolError;
26use sp_runtime::transaction_validity::InvalidTransaction;
27
28#[derive(Debug, thiserror::Error)]
30pub enum Error {
31 #[error("Transaction pool error: {}", .0)]
33 Pool(#[from] PoolError),
34 #[error("Extrinsic verification error: {}", .0)]
36 Verification(Box<dyn std::error::Error + Send + Sync>),
37}
38
39impl<Hash> From<Error> for TransactionEvent<Hash> {
40 fn from(e: Error) -> Self {
41 match e {
42 Error::Verification(e) => TransactionEvent::Invalid(TransactionError {
43 error: format!("Verification error: {}", e),
44 }),
45 Error::Pool(PoolError::InvalidTransaction(InvalidTransaction::Custom(e))) => {
46 TransactionEvent::Invalid(TransactionError {
47 error: format!("Invalid transaction with custom error: {}", e),
48 })
49 },
50 Error::Pool(PoolError::InvalidTransaction(InvalidTransaction::Module(e))) => {
51 TransactionEvent::Invalid(TransactionError {
52 error: format!(
53 "Invalid transaction: module invalidity (pallet: {}, error: {})",
54 e.index, e.error
55 ),
56 })
57 },
58 Error::Pool(PoolError::InvalidTransaction(e)) => {
59 let msg: &str = e.into();
60 TransactionEvent::Invalid(TransactionError {
61 error: format!("Invalid transaction: {}", msg),
62 })
63 },
64 Error::Pool(PoolError::UnknownTransaction(e)) => {
65 let msg: &str = e.into();
66 TransactionEvent::Invalid(TransactionError {
67 error: format!("Unknown transaction validity: {}", msg),
68 })
69 },
70 Error::Pool(PoolError::TemporarilyBanned) => {
71 TransactionEvent::Invalid(TransactionError {
72 error: "Transaction is temporarily banned".into(),
73 })
74 },
75 Error::Pool(PoolError::AlreadyImported(_)) => {
76 TransactionEvent::Invalid(TransactionError {
77 error: "Transaction is already imported".into(),
78 })
79 },
80 Error::Pool(PoolError::TooLowPriority { old, new }) => {
81 TransactionEvent::Invalid(TransactionError {
82 error: format!(
83 "The priority of the transaction is too low (pool {} > current {})",
84 old, new
85 ),
86 })
87 },
88 Error::Pool(PoolError::CycleDetected) => TransactionEvent::Invalid(TransactionError {
89 error: "The transaction contains a cyclic dependency".into(),
90 }),
91 Error::Pool(PoolError::ImmediatelyDropped) => {
92 TransactionEvent::Invalid(TransactionError {
93 error: "The transaction could not enter the pool because of the limit".into(),
94 })
95 },
96 Error::Pool(PoolError::Unactionable) => TransactionEvent::Invalid(TransactionError {
97 error: "Transaction cannot be propagated and the local node does not author blocks"
98 .into(),
99 }),
100 Error::Pool(PoolError::NoTagsProvided) => TransactionEvent::Invalid(TransactionError {
101 error: "Transaction does not provide any tags, so the pool cannot identify it"
102 .into(),
103 }),
104 Error::Pool(PoolError::InvalidBlockId(_)) => {
105 TransactionEvent::Invalid(TransactionError {
106 error: "The provided block ID is not valid".into(),
107 })
108 },
109 Error::Pool(PoolError::RejectedFutureTransaction) => {
110 TransactionEvent::Invalid(TransactionError {
111 error: "The pool is not accepting future transactions".into(),
112 })
113 },
114 }
115 }
116}
117
118#[derive(Debug, thiserror::Error)]
120pub enum ErrorBroadcast {
121 #[error("Invalid operation id")]
123 InvalidOperationID,
124}
125
126pub mod json_rpc_spec {
129 pub const INVALID_PARAM_ERROR: i32 = -32602;
131}
132
133impl From<ErrorBroadcast> for ErrorObject<'static> {
134 fn from(e: ErrorBroadcast) -> Self {
135 let msg = e.to_string();
136
137 match e {
138 ErrorBroadcast::InvalidOperationID => {
139 ErrorObject::owned(json_rpc_spec::INVALID_PARAM_ERROR, msg, None::<()>)
140 },
141 }
142 }
143}
144
145#[cfg(test)]
146mod tests {
147 use super::*;
148 use sp_runtime::ModuleInvalidity;
149
150 #[test]
151 fn module_invalidity_becomes_invalid_transaction_event() {
152 let on_node = ModuleInvalidity { index: 42, error: 1 };
153 let err = Error::Pool(PoolError::InvalidTransaction(InvalidTransaction::Module(on_node)));
154
155 let event: TransactionEvent<u64> = err.into();
156
157 assert_eq!(
158 event,
159 TransactionEvent::Invalid(TransactionError {
160 error: "Invalid transaction: module invalidity (pallet: 42, error: 1)".into(),
161 })
162 );
163 }
164}