mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-14 02:51:08 +00:00
Pass transaction source to validate_transaction (#5366)
* WiP * Support source in the runtime API. * Finish implementation in txpool. * Fix warning. * Fix tests. * Apply suggestions from code review Co-Authored-By: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Co-Authored-By: Nikolay Volf <nikvolf@gmail.com> * Extra changes. * Fix test and benches. * fix test * Fix test & benches again. * Fix tests. * Update bumpalo * Fix doc test. * Fix doctest. * Fix doctest. Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Co-authored-by: Nikolay Volf <nikvolf@gmail.com>
This commit is contained in:
@@ -51,7 +51,9 @@ use sp_core::crypto::KeyTypeId;
|
||||
use sp_runtime::{
|
||||
offchain::{http, Duration, storage::StorageValueRef},
|
||||
traits::Zero,
|
||||
transaction_validity::{InvalidTransaction, ValidTransaction, TransactionValidity},
|
||||
transaction_validity::{
|
||||
InvalidTransaction, ValidTransaction, TransactionValidity, TransactionSource,
|
||||
},
|
||||
};
|
||||
use sp_std::{vec, vec::Vec};
|
||||
use lite_json::json::JsonValue;
|
||||
@@ -509,7 +511,10 @@ impl<T: Trait> frame_support::unsigned::ValidateUnsigned for Module<T> {
|
||||
/// By default unsigned transactions are disallowed, but implementing the validator
|
||||
/// here we make sure that some particular calls (the ones produced by offchain worker)
|
||||
/// are being whitelisted and marked as valid.
|
||||
fn validate_unsigned(call: &Self::Call) -> TransactionValidity {
|
||||
fn validate_unsigned(
|
||||
_source: TransactionSource,
|
||||
call: &Self::Call,
|
||||
) -> TransactionValidity {
|
||||
// Firstly let's check that we call the right function.
|
||||
if let Call::submit_price_unsigned(block_number, new_price) = call {
|
||||
// Now let's check if the transaction has any chance to succeed.
|
||||
|
||||
@@ -59,12 +59,14 @@
|
||||
//! # pub type Balances = u64;
|
||||
//! # pub type AllModules = u64;
|
||||
//! # pub enum Runtime {};
|
||||
//! # use sp_runtime::transaction_validity::{TransactionValidity, UnknownTransaction};
|
||||
//! # use sp_runtime::transaction_validity::{
|
||||
//! TransactionValidity, UnknownTransaction, TransactionSource,
|
||||
//! # };
|
||||
//! # use sp_runtime::traits::ValidateUnsigned;
|
||||
//! # impl ValidateUnsigned for Runtime {
|
||||
//! # type Call = ();
|
||||
//! #
|
||||
//! # fn validate_unsigned(_call: &Self::Call) -> TransactionValidity {
|
||||
//! # fn validate_unsigned(_source: TransactionSource, _call: &Self::Call) -> TransactionValidity {
|
||||
//! # UnknownTransaction::NoUnsignedValidator.into()
|
||||
//! # }
|
||||
//! # }
|
||||
@@ -85,7 +87,7 @@ use sp_runtime::{
|
||||
self, Header, Zero, One, Checkable, Applyable, CheckEqual, ValidateUnsigned, NumberFor,
|
||||
Block as BlockT, Dispatchable, Saturating,
|
||||
},
|
||||
transaction_validity::TransactionValidity,
|
||||
transaction_validity::{TransactionValidity, TransactionSource},
|
||||
};
|
||||
use codec::{Codec, Encode};
|
||||
use frame_system::{extrinsics_root, DigestOf};
|
||||
@@ -338,12 +340,15 @@ where
|
||||
/// side-effects; it merely checks whether the transaction would panic if it were included or not.
|
||||
///
|
||||
/// Changes made to storage should be discarded.
|
||||
pub fn validate_transaction(uxt: Block::Extrinsic) -> TransactionValidity {
|
||||
pub fn validate_transaction(
|
||||
source: TransactionSource,
|
||||
uxt: Block::Extrinsic,
|
||||
) -> TransactionValidity {
|
||||
let encoded_len = uxt.using_encoded(|d| d.len());
|
||||
let xt = uxt.check(&Default::default())?;
|
||||
|
||||
let dispatch_info = xt.get_dispatch_info();
|
||||
xt.validate::<UnsignedValidator>(dispatch_info, encoded_len)
|
||||
xt.validate::<UnsignedValidator>(source, dispatch_info, encoded_len)
|
||||
}
|
||||
|
||||
/// Start an offchain worker and generate extrinsics.
|
||||
@@ -511,7 +516,10 @@ mod tests {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn validate_unsigned(call: &Self::Call) -> TransactionValidity {
|
||||
fn validate_unsigned(
|
||||
_source: TransactionSource,
|
||||
call: &Self::Call,
|
||||
) -> TransactionValidity {
|
||||
match call {
|
||||
Call::Balances(BalancesCall::set_balance(_, _, _)) => Ok(Default::default()),
|
||||
_ => UnknownTransaction::NoUnsignedValidator.into(),
|
||||
@@ -725,7 +733,10 @@ mod tests {
|
||||
let mut t = new_test_ext(1);
|
||||
|
||||
t.execute_with(|| {
|
||||
assert_eq!(Executive::validate_transaction(xt.clone()), Ok(Default::default()));
|
||||
assert_eq!(
|
||||
Executive::validate_transaction(TransactionSource::InBlock, xt.clone()),
|
||||
Ok(Default::default()),
|
||||
);
|
||||
assert_eq!(Executive::apply_extrinsic(xt), Ok(Err(DispatchError::BadOrigin)));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ use frame_system::RawOrigin;
|
||||
use frame_benchmarking::benchmarks;
|
||||
use sp_core::offchain::{OpaquePeerId, OpaqueMultiaddr};
|
||||
use sp_runtime::traits::{ValidateUnsigned, Zero};
|
||||
use sp_runtime::transaction_validity::TransactionSource;
|
||||
|
||||
use crate::Module as ImOnline;
|
||||
|
||||
@@ -72,7 +73,7 @@ benchmarks! {
|
||||
let (input_heartbeat, signature) = create_heartbeat::<T>(k, e)?;
|
||||
let call = Call::heartbeat(input_heartbeat, signature);
|
||||
}: {
|
||||
ImOnline::<T>::validate_unsigned(&call)?;
|
||||
ImOnline::<T>::validate_unsigned(TransactionSource::InBlock, &call)?;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@ use sp_runtime::{
|
||||
RuntimeDebug,
|
||||
traits::{Convert, Member, Saturating, AtLeast32Bit}, Perbill, PerThing,
|
||||
transaction_validity::{
|
||||
TransactionValidity, ValidTransaction, InvalidTransaction,
|
||||
TransactionValidity, ValidTransaction, InvalidTransaction, TransactionSource,
|
||||
TransactionPriority,
|
||||
},
|
||||
};
|
||||
@@ -624,7 +624,10 @@ impl<T: Trait> pallet_session::OneSessionHandler<T::AccountId> for Module<T> {
|
||||
impl<T: Trait> frame_support::unsigned::ValidateUnsigned for Module<T> {
|
||||
type Call = Call<T>;
|
||||
|
||||
fn validate_unsigned(call: &Self::Call) -> TransactionValidity {
|
||||
fn validate_unsigned(
|
||||
_source: TransactionSource,
|
||||
call: &Self::Call,
|
||||
) -> TransactionValidity {
|
||||
if let Call::heartbeat(heartbeat, signature) = call {
|
||||
if <Module<T>>::is_online(heartbeat.authority_index) {
|
||||
// we already received a heartbeat for this authority
|
||||
|
||||
@@ -89,7 +89,7 @@ fn construct_runtime_parsed(definition: RuntimeDefinition) -> Result<TokenStream
|
||||
let inherent = decl_outer_inherent(&block, &unchecked_extrinsic, modules.iter(), &scrate);
|
||||
let validate_unsigned = decl_validate_unsigned(&name, modules.iter(), &scrate);
|
||||
|
||||
Ok(quote!(
|
||||
let res = quote!(
|
||||
#scrate_decl
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq)]
|
||||
@@ -119,8 +119,9 @@ fn construct_runtime_parsed(definition: RuntimeDefinition) -> Result<TokenStream
|
||||
#inherent
|
||||
|
||||
#validate_unsigned
|
||||
)
|
||||
.into())
|
||||
);
|
||||
|
||||
Ok(res.into())
|
||||
}
|
||||
|
||||
fn decl_validate_unsigned<'a>(
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
pub use crate::sp_runtime::traits::ValidateUnsigned;
|
||||
#[doc(hidden)]
|
||||
pub use crate::sp_runtime::transaction_validity::{
|
||||
TransactionValidity, UnknownTransaction, TransactionValidityError,
|
||||
TransactionValidity, UnknownTransaction, TransactionValidityError, TransactionSource,
|
||||
};
|
||||
|
||||
|
||||
@@ -34,7 +34,8 @@ pub use crate::sp_runtime::transaction_validity::{
|
||||
/// # impl frame_support::unsigned::ValidateUnsigned for Module {
|
||||
/// # type Call = Call;
|
||||
/// #
|
||||
/// # fn validate_unsigned(call: &Self::Call) -> frame_support::unsigned::TransactionValidity {
|
||||
/// # fn validate_unsigned(_source: frame_support::unsigned::TransactionSource, _call: &Self::Call)
|
||||
/// -> frame_support::unsigned::TransactionValidity {
|
||||
/// # unimplemented!();
|
||||
/// # }
|
||||
/// # }
|
||||
@@ -78,10 +79,14 @@ macro_rules! impl_outer_validate_unsigned {
|
||||
}
|
||||
}
|
||||
|
||||
fn validate_unsigned(call: &Self::Call) -> $crate::unsigned::TransactionValidity {
|
||||
fn validate_unsigned(
|
||||
#[allow(unused_variables)]
|
||||
source: $crate::unsigned::TransactionSource,
|
||||
call: &Self::Call,
|
||||
) -> $crate::unsigned::TransactionValidity {
|
||||
#[allow(unreachable_patterns)]
|
||||
match call {
|
||||
$( Call::$module(inner_call) => $module::validate_unsigned(inner_call), )*
|
||||
$( Call::$module(inner_call) => $module::validate_unsigned(source, inner_call), )*
|
||||
_ => $crate::unsigned::UnknownTransaction::NoUnsignedValidator.into(),
|
||||
}
|
||||
}
|
||||
@@ -110,7 +115,10 @@ mod test_partial_and_full_call {
|
||||
impl super::super::ValidateUnsigned for Module {
|
||||
type Call = Call;
|
||||
|
||||
fn validate_unsigned(_call: &Self::Call) -> super::super::TransactionValidity {
|
||||
fn validate_unsigned(
|
||||
_source: super::super::TransactionSource,
|
||||
_call: &Self::Call
|
||||
) -> super::super::TransactionValidity {
|
||||
unimplemented!();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user