referrerpolicy=no-referrer-when-downgrade

sc_rpc_spec_v2/transaction/
error.rs

1// This file is part of Substrate.
2
3// Copyright (C) Parity Technologies (UK) Ltd.
4// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
5
6// This program is free software: you can redistribute it and/or modify
7// it under the terms of the GNU General Public License as published by
8// the Free Software Foundation, either version 3 of the License, or
9// (at your option) any later version.
10
11// This program is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// You should have received a copy of the GNU General Public License
17// along with this program. If not, see <https://www.gnu.org/licenses/>.
18
19//! Transaction RPC errors.
20//!
21//! Errors are interpreted as transaction events for subscriptions.
22
23use 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/// Transaction RPC errors.
29#[derive(Debug, thiserror::Error)]
30pub enum Error {
31	/// Transaction pool error.
32	#[error("Transaction pool error: {}", .0)]
33	Pool(#[from] PoolError),
34	/// Verification error.
35	#[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			Error::Pool(PoolError::InvalidTransaction(e)) => {
50				let msg: &str = e.into();
51				TransactionEvent::Invalid(TransactionError {
52					error: format!("Invalid transaction: {}", msg),
53				})
54			},
55			Error::Pool(PoolError::UnknownTransaction(e)) => {
56				let msg: &str = e.into();
57				TransactionEvent::Invalid(TransactionError {
58					error: format!("Unknown transaction validity: {}", msg),
59				})
60			},
61			Error::Pool(PoolError::TemporarilyBanned) =>
62				TransactionEvent::Invalid(TransactionError {
63					error: "Transaction is temporarily banned".into(),
64				}),
65			Error::Pool(PoolError::AlreadyImported(_)) =>
66				TransactionEvent::Invalid(TransactionError {
67					error: "Transaction is already imported".into(),
68				}),
69			Error::Pool(PoolError::TooLowPriority { old, new }) =>
70				TransactionEvent::Invalid(TransactionError {
71					error: format!(
72						"The priority of the transaction is too low (pool {} > current {})",
73						old, new
74					),
75				}),
76			Error::Pool(PoolError::CycleDetected) => TransactionEvent::Invalid(TransactionError {
77				error: "The transaction contains a cyclic dependency".into(),
78			}),
79			Error::Pool(PoolError::ImmediatelyDropped) =>
80				TransactionEvent::Invalid(TransactionError {
81					error: "The transaction could not enter the pool because of the limit".into(),
82				}),
83			Error::Pool(PoolError::Unactionable) => TransactionEvent::Invalid(TransactionError {
84				error: "Transaction cannot be propagated and the local node does not author blocks"
85					.into(),
86			}),
87			Error::Pool(PoolError::NoTagsProvided) => TransactionEvent::Invalid(TransactionError {
88				error: "Transaction does not provide any tags, so the pool cannot identify it"
89					.into(),
90			}),
91			Error::Pool(PoolError::InvalidBlockId(_)) =>
92				TransactionEvent::Invalid(TransactionError {
93					error: "The provided block ID is not valid".into(),
94				}),
95			Error::Pool(PoolError::RejectedFutureTransaction) =>
96				TransactionEvent::Invalid(TransactionError {
97					error: "The pool is not accepting future transactions".into(),
98				}),
99		}
100	}
101}
102
103/// TransactionBroadcast error.
104#[derive(Debug, thiserror::Error)]
105pub enum ErrorBroadcast {
106	/// The provided operation ID is invalid.
107	#[error("Invalid operation id")]
108	InvalidOperationID,
109}
110
111/// General purpose errors, as defined in
112/// <https://www.jsonrpc.org/specification#error_object>.
113pub mod json_rpc_spec {
114	/// Invalid parameter error.
115	pub const INVALID_PARAM_ERROR: i32 = -32602;
116}
117
118impl From<ErrorBroadcast> for ErrorObject<'static> {
119	fn from(e: ErrorBroadcast) -> Self {
120		let msg = e.to_string();
121
122		match e {
123			ErrorBroadcast::InvalidOperationID =>
124				ErrorObject::owned(json_rpc_spec::INVALID_PARAM_ERROR, msg, None::<()>),
125		}
126	}
127}