sc_transaction_pool_api/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 pool errors.
20
21use sp_runtime::transaction_validity::{
22 InvalidTransaction, TransactionPriority as Priority, UnknownTransaction,
23};
24
25/// Transaction pool result.
26pub type Result<T> = std::result::Result<T, Error>;
27
28/// Transaction pool error type.
29#[derive(Debug, thiserror::Error)]
30#[allow(missing_docs)]
31pub enum Error {
32 #[error("Unknown transaction validity: {0:?}")]
33 UnknownTransaction(UnknownTransaction),
34
35 #[error("Invalid transaction validity: {0:?}")]
36 InvalidTransaction(InvalidTransaction),
37
38 /// The transaction validity returned no "provides" tag.
39 ///
40 /// Such transactions are not accepted to the pool, since we use those tags
41 /// to define identity of transactions (occupancy of the same "slot").
42 #[error("Transaction does not provide any tags, so the pool can't identify it")]
43 NoTagsProvided,
44
45 #[error("Transaction temporarily Banned")]
46 TemporarilyBanned,
47
48 #[error("[{0:?}] Already imported")]
49 AlreadyImported(Box<dyn std::any::Any + Send + Sync>),
50
51 #[error("Too low priority ({} > {})", old, new)]
52 TooLowPriority {
53 /// Transaction already in the pool.
54 old: Priority,
55 /// Transaction entering the pool.
56 new: Priority,
57 },
58 #[error("Transaction with cyclic dependency")]
59 CycleDetected,
60
61 #[error("Transaction couldn't enter the pool because of the limit")]
62 ImmediatelyDropped,
63
64 #[error("Transaction cannot be propagated and the local node does not author blocks")]
65 Unactionable,
66
67 #[error("{0}")]
68 InvalidBlockId(String),
69
70 #[error("The pool is not accepting future transactions")]
71 RejectedFutureTransaction,
72}
73
74impl Error {
75 /// Returns true if the transaction could be re-submitted to the pool in the future.
76 ///
77 /// For example, `Error::ImmediatelyDropped` is retriable, because the transaction
78 /// may enter the pool if there is space for it in the future.
79 pub fn is_retriable(&self) -> bool {
80 match self {
81 // An invalid transaction is temporarily banned, however it can
82 // become valid at a later time.
83 Error::TemporarilyBanned |
84 // The pool is full at the moment.
85 Error::ImmediatelyDropped |
86 // The block id is not known to the pool.
87 // The node might be lagging behind, or during a warp sync.
88 Error::InvalidBlockId(_) |
89 // The pool is configured to not accept future transactions.
90 Error::RejectedFutureTransaction => {
91 true
92 }
93 _ => false
94 }
95 }
96}
97
98/// Transaction pool error conversion.
99pub trait IntoPoolError: std::error::Error + Send + Sized + Sync {
100 /// Try to extract original `Error`
101 ///
102 /// This implementation is optional and used only to
103 /// provide more descriptive error messages for end users
104 /// of RPC API.
105 fn into_pool_error(self) -> std::result::Result<Error, Self> {
106 Err(self)
107 }
108}
109
110impl IntoPoolError for Error {
111 fn into_pool_error(self) -> std::result::Result<Error, Self> {
112 Ok(self)
113 }
114}