// This file is part of Substrate.
// Copyright (C) 2022 Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
//! Transaction RPC errors.
//!
//! Errors are interpreted as transaction events for subscriptions.
use crate::transaction::event::{TransactionError, TransactionEvent};
use sc_transaction_pool_api::error::Error as PoolError;
use sp_runtime::transaction_validity::InvalidTransaction;
/// Transaction RPC errors.
#[derive(Debug, thiserror::Error)]
pub enum Error {
/// Transaction pool error.
#[error("Transaction pool error: {}", .0)]
Pool(#[from] PoolError),
/// Verification error.
#[error("Extrinsic verification error: {}", .0)]
Verification(Box),
}
impl From for TransactionEvent {
fn from(e: Error) -> Self {
match e {
Error::Verification(e) => TransactionEvent::Invalid(TransactionError {
error: format!("Verification error: {}", e),
}),
Error::Pool(PoolError::InvalidTransaction(InvalidTransaction::Custom(e))) =>
TransactionEvent::Invalid(TransactionError {
error: format!("Invalid transaction with custom error: {}", e),
}),
Error::Pool(PoolError::InvalidTransaction(e)) => {
let msg: &str = e.into();
TransactionEvent::Invalid(TransactionError {
error: format!("Invalid transaction: {}", msg),
})
},
Error::Pool(PoolError::UnknownTransaction(e)) => {
let msg: &str = e.into();
TransactionEvent::Invalid(TransactionError {
error: format!("Unknown transaction validity: {}", msg),
})
},
Error::Pool(PoolError::TemporarilyBanned) =>
TransactionEvent::Invalid(TransactionError {
error: "Transaction is temporarily banned".into(),
}),
Error::Pool(PoolError::AlreadyImported(_)) =>
TransactionEvent::Invalid(TransactionError {
error: "Transaction is already imported".into(),
}),
Error::Pool(PoolError::TooLowPriority { old, new }) =>
TransactionEvent::Invalid(TransactionError {
error: format!(
"The priority of the transactin is too low (pool {} > current {})",
old, new
),
}),
Error::Pool(PoolError::CycleDetected) => TransactionEvent::Invalid(TransactionError {
error: "The transaction contains a cyclic dependency".into(),
}),
Error::Pool(PoolError::ImmediatelyDropped) =>
TransactionEvent::Invalid(TransactionError {
error: "The transaction could not enter the pool because of the limit".into(),
}),
Error::Pool(PoolError::Unactionable) => TransactionEvent::Invalid(TransactionError {
error: "Transaction cannot be propagated and the local node does not author blocks"
.into(),
}),
Error::Pool(PoolError::NoTagsProvided) => TransactionEvent::Invalid(TransactionError {
error: "Transaction does not provide any tags, so the pool cannot identify it"
.into(),
}),
Error::Pool(PoolError::InvalidBlockId(_)) =>
TransactionEvent::Invalid(TransactionError {
error: "The provided block ID is not valid".into(),
}),
Error::Pool(PoolError::RejectedFutureTransaction) =>
TransactionEvent::Invalid(TransactionError {
error: "The pool is not accepting future transactions".into(),
}),
}
}
}