mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-28 19:07:57 +00:00
rpc-v2/transaction: Generate Invalid events and add tests (#3784)
This PR ensures that the transaction API generates an `Invalid` events for transaction bytes that fail to decode. The spec mentioned the `Invalid` event at the jsonrpc error section, however this spec PR makes things clearer: - https://github.com/paritytech/json-rpc-interface-spec/pull/146 While at it have discovered an inconsistency with the generated events. The drop event from the transaction pool was incorrectly mapped to the `invalid` event. Added tests for the API stabilize the API soon: - https://github.com/paritytech/json-rpc-interface-spec/pull/144 Closes: https://github.com/paritytech/polkadot-sdk/issues/3083 cc @paritytech/subxt-team --------- Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
This commit is contained in:
@@ -28,8 +28,8 @@ use crate::{
|
||||
};
|
||||
use codec::Decode;
|
||||
use futures::{StreamExt, TryFutureExt};
|
||||
use jsonrpsee::{core::async_trait, types::error::ErrorObject, PendingSubscriptionSink};
|
||||
use sc_rpc::utils::pipe_from_stream;
|
||||
use jsonrpsee::{core::async_trait, PendingSubscriptionSink};
|
||||
use sc_rpc::utils::{pipe_from_stream, to_sub_message};
|
||||
use sc_transaction_pool_api::{
|
||||
error::IntoPoolError, BlockHash, TransactionFor, TransactionPool, TransactionSource,
|
||||
TransactionStatus,
|
||||
@@ -39,6 +39,8 @@ use sp_core::Bytes;
|
||||
use sp_runtime::traits::Block as BlockT;
|
||||
use std::sync::Arc;
|
||||
|
||||
pub(crate) const LOG_TARGET: &str = "rpc-spec-v2";
|
||||
|
||||
/// An API for transaction RPC calls.
|
||||
pub struct Transaction<Pool, Client> {
|
||||
/// Substrate client.
|
||||
@@ -63,13 +65,6 @@ impl<Pool, Client> Transaction<Pool, Client> {
|
||||
/// some unique transactions via RPC and have them included in the pool.
|
||||
const TX_SOURCE: TransactionSource = TransactionSource::External;
|
||||
|
||||
/// Extrinsic has an invalid format.
|
||||
///
|
||||
/// # Note
|
||||
///
|
||||
/// This is similar to the old `author` API error code.
|
||||
const BAD_FORMAT: i32 = 1001;
|
||||
|
||||
#[async_trait]
|
||||
impl<Pool, Client> TransactionApiServer<BlockHash<Pool>> for Transaction<Pool, Client>
|
||||
where
|
||||
@@ -83,17 +78,21 @@ where
|
||||
let pool = self.pool.clone();
|
||||
|
||||
let fut = async move {
|
||||
// This is the only place where the RPC server can return an error for this
|
||||
// subscription. Other defects must be signaled as events to the sink.
|
||||
let decoded_extrinsic = match TransactionFor::<Pool>::decode(&mut &xt[..]) {
|
||||
Ok(decoded_extrinsic) => decoded_extrinsic,
|
||||
Err(e) => {
|
||||
let err = ErrorObject::owned(
|
||||
BAD_FORMAT,
|
||||
format!("Extrinsic has invalid format: {}", e),
|
||||
None::<()>,
|
||||
log::debug!(target: LOG_TARGET, "Extrinsic bytes cannot be decoded: {:?}", e);
|
||||
|
||||
let Ok(sink) = pending.accept().await else { return };
|
||||
|
||||
// The transaction is invalid.
|
||||
let msg = to_sub_message(
|
||||
&sink,
|
||||
&TransactionEvent::Invalid::<BlockHash<Pool>>(TransactionError {
|
||||
error: "Extrinsic bytes cannot be decoded".into(),
|
||||
}),
|
||||
);
|
||||
let _ = pending.reject(err).await;
|
||||
let _ = sink.send(msg).await;
|
||||
return
|
||||
},
|
||||
};
|
||||
@@ -147,7 +146,7 @@ pub fn handle_event<Hash: Clone, BlockHash: Clone>(
|
||||
TransactionStatus::Usurped(_) => Some(TransactionEvent::Invalid(TransactionError {
|
||||
error: "Extrinsic was rendered invalid by another extrinsic".into(),
|
||||
})),
|
||||
TransactionStatus::Dropped => Some(TransactionEvent::Invalid(TransactionError {
|
||||
TransactionStatus::Dropped => Some(TransactionEvent::Dropped(TransactionDropped {
|
||||
error: "Extrinsic dropped from the pool due to exceeding limits".into(),
|
||||
})),
|
||||
TransactionStatus::Invalid => Some(TransactionEvent::Invalid(TransactionError {
|
||||
|
||||
Reference in New Issue
Block a user