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			},
50			Error::Pool(PoolError::InvalidTransaction(e)) => {
51				let msg: &str = e.into();
52				TransactionEvent::Invalid(TransactionError {
53					error: format!("Invalid transaction: {}", msg),
54				})
55			},
56			Error::Pool(PoolError::UnknownTransaction(e)) => {
57				let msg: &str = e.into();
58				TransactionEvent::Invalid(TransactionError {
59					error: format!("Unknown transaction validity: {}", msg),
60				})
61			},
62			Error::Pool(PoolError::TemporarilyBanned) => {
63				TransactionEvent::Invalid(TransactionError {
64					error: "Transaction is temporarily banned".into(),
65				})
66			},
67			Error::Pool(PoolError::AlreadyImported(_)) => {
68				TransactionEvent::Invalid(TransactionError {
69					error: "Transaction is already imported".into(),
70				})
71			},
72			Error::Pool(PoolError::TooLowPriority { old, new }) => {
73				TransactionEvent::Invalid(TransactionError {
74					error: format!(
75						"The priority of the transaction is too low (pool {} > current {})",
76						old, new
77					),
78				})
79			},
80			Error::Pool(PoolError::CycleDetected) => TransactionEvent::Invalid(TransactionError {
81				error: "The transaction contains a cyclic dependency".into(),
82			}),
83			Error::Pool(PoolError::ImmediatelyDropped) => {
84				TransactionEvent::Invalid(TransactionError {
85					error: "The transaction could not enter the pool because of the limit".into(),
86				})
87			},
88			Error::Pool(PoolError::Unactionable) => TransactionEvent::Invalid(TransactionError {
89				error: "Transaction cannot be propagated and the local node does not author blocks"
90					.into(),
91			}),
92			Error::Pool(PoolError::NoTagsProvided) => TransactionEvent::Invalid(TransactionError {
93				error: "Transaction does not provide any tags, so the pool cannot identify it"
94					.into(),
95			}),
96			Error::Pool(PoolError::InvalidBlockId(_)) => {
97				TransactionEvent::Invalid(TransactionError {
98					error: "The provided block ID is not valid".into(),
99				})
100			},
101			Error::Pool(PoolError::RejectedFutureTransaction) => {
102				TransactionEvent::Invalid(TransactionError {
103					error: "The pool is not accepting future transactions".into(),
104				})
105			},
106		}
107	}
108}
109
110/// TransactionBroadcast error.
111#[derive(Debug, thiserror::Error)]
112pub enum ErrorBroadcast {
113	/// The provided operation ID is invalid.
114	#[error("Invalid operation id")]
115	InvalidOperationID,
116}
117
118/// General purpose errors, as defined in
119/// <https://www.jsonrpc.org/specification#error_object>.
120pub mod json_rpc_spec {
121	/// Invalid parameter error.
122	pub const INVALID_PARAM_ERROR: i32 = -32602;
123}
124
125impl From<ErrorBroadcast> for ErrorObject<'static> {
126	fn from(e: ErrorBroadcast) -> Self {
127		let msg = e.to_string();
128
129		match e {
130			ErrorBroadcast::InvalidOperationID => {
131				ErrorObject::owned(json_rpc_spec::INVALID_PARAM_ERROR, msg, None::<()>)
132			},
133		}
134	}
135}