Skip to content

Commit 10cd967

Browse files
committed
Removed deprecated ValidateUnsigned
1 parent b48ef2e commit 10cd967

File tree

3 files changed

+183
-38
lines changed

3 files changed

+183
-38
lines changed

pallets/transaction-storage/src/lib.rs

Lines changed: 94 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,22 @@ pub mod pallet {
344344
#[pallet::call_index(0)]
345345
#[pallet::weight(T::WeightInfo::store(data.len() as u32))]
346346
#[pallet::feeless_if(|origin: &OriginFor<T>, data: &Vec<u8>| -> bool { /*TODO: add here correct validation */ true })]
347-
pub fn store(_origin: OriginFor<T>, data: Vec<u8>) -> DispatchResult {
347+
#[pallet::authorize(|_source, data| {
348+
Pallet::<T>::to_validity_with_refund(
349+
Pallet::<T>::check_unsigned_store(data.as_slice(), CheckContext::Validate),
350+
)
351+
})]
352+
#[pallet::weight_of_authorize(Weight::zero())]
353+
pub fn store(origin: OriginFor<T>, data: Vec<u8>) -> DispatchResult {
354+
let is_authorized = matches!(
355+
origin.into(),
356+
Ok(frame_system::RawOrigin::Authorized)
357+
);
358+
if is_authorized {
359+
Self::check_unsigned_store(data.as_slice(), CheckContext::PreDispatch)
360+
.map_err(Self::dispatch_error_from_validity)?;
361+
}
362+
348363
// In the case of a regular unsigned transaction, this should have been checked by
349364
// pre_dispatch. In the case of a regular signed transaction, this should have been
350365
// checked by pre_dispatch_signed.
@@ -395,11 +410,28 @@ pub mod pallet {
395410
/// O(1).
396411
#[pallet::call_index(1)]
397412
#[pallet::weight(T::WeightInfo::renew())]
413+
#[pallet::authorize(|_source, block, index| {
414+
Pallet::<T>::to_validity_with_refund(Pallet::<T>::check_unsigned_renew(
415+
block,
416+
index,
417+
CheckContext::Validate,
418+
))
419+
})]
420+
#[pallet::weight_of_authorize(Weight::zero())]
398421
pub fn renew(
399-
_origin: OriginFor<T>,
422+
origin: OriginFor<T>,
400423
block: BlockNumberFor<T>,
401424
index: u32,
402425
) -> DispatchResultWithPostInfo {
426+
let is_authorized = matches!(
427+
origin.into(),
428+
Ok(frame_system::RawOrigin::Authorized)
429+
);
430+
if is_authorized {
431+
Self::check_unsigned_renew(&block, &index, CheckContext::PreDispatch)
432+
.map_err(Self::dispatch_error_from_validity)?;
433+
}
434+
403435
let info = Self::transaction_info(block, index).ok_or(Error::<T>::RenewedNotFound)?;
404436

405437
// In the case of a regular unsigned transaction, this should have been checked by
@@ -531,6 +563,12 @@ pub mod pallet {
531563
/// when successful.
532564
#[pallet::call_index(5)]
533565
#[pallet::weight(T::WeightInfo::remove_expired_account_authorization())]
566+
#[pallet::authorize(|_source, who| {
567+
Pallet::<T>::to_validity_with_refund(
568+
Pallet::<T>::check_unsigned_remove_expired_account(who, CheckContext::Validate),
569+
)
570+
})]
571+
#[pallet::weight_of_authorize(Weight::zero())]
534572
pub fn remove_expired_account_authorization(
535573
_origin: OriginFor<T>,
536574
who: T::AccountId,
@@ -551,6 +589,12 @@ pub mod pallet {
551589
/// when successful.
552590
#[pallet::call_index(6)]
553591
#[pallet::weight(T::WeightInfo::remove_expired_preimage_authorization())]
592+
#[pallet::authorize(|_source, hash| {
593+
Pallet::<T>::to_validity_with_refund(
594+
Pallet::<T>::check_unsigned_remove_expired_preimage(hash, CheckContext::Validate),
595+
)
596+
})]
597+
#[pallet::weight_of_authorize(Weight::zero())]
554598
pub fn remove_expired_preimage_authorization(
555599
_origin: OriginFor<T>,
556600
content_hash: ContentHash,
@@ -719,25 +763,20 @@ pub mod pallet {
719763
}
720764
}
721765

722-
#[pallet::validate_unsigned]
723-
impl<T: Config> ValidateUnsigned for Pallet<T> {
724-
type Call = Call<T>;
725-
726-
fn validate_unsigned(_source: TransactionSource, call: &Self::Call) -> TransactionValidity {
727-
Self::check_unsigned(call, CheckContext::Validate)?.ok_or(IMPOSSIBLE.into())
766+
impl<T: Config> Pallet<T> {
767+
fn to_validity_with_refund(
768+
result: Result<Option<ValidTransaction>, TransactionValidityError>,
769+
) -> Result<(ValidTransaction, Weight), TransactionValidityError> {
770+
let validity =
771+
result?.ok_or(TransactionValidityError::Invalid(IMPOSSIBLE))?;
772+
Ok((validity, Weight::zero()))
728773
}
729774

730-
fn pre_dispatch(call: &Self::Call) -> Result<(), TransactionValidityError> {
731-
// Allow inherents here.
732-
if Self::is_inherent(call) {
733-
return Ok(());
734-
}
735-
736-
Self::check_unsigned(call, CheckContext::PreDispatch).map(|_| ())
775+
fn dispatch_error_from_validity(error: TransactionValidityError) -> DispatchError {
776+
let message: &'static str = error.into();
777+
DispatchError::Other(message)
737778
}
738-
}
739779

740-
impl<T: Config> Pallet<T> {
741780
/// Returns `true` if the system is beyond the given expiration point.
742781
fn expired(expiration: BlockNumberFor<T>) -> bool {
743782
let now = frame_system::Pallet::<T>::block_number();
@@ -1013,25 +1052,34 @@ pub mod pallet {
10131052
}))
10141053
}
10151054

1016-
fn check_unsigned(
1017-
call: &Call<T>,
1055+
fn check_unsigned_store(
1056+
data: &[u8],
10181057
context: CheckContext,
10191058
) -> Result<Option<ValidTransaction>, TransactionValidityError> {
1020-
match call {
1021-
Call::<T>::store { data } => Self::check_store_renew_unsigned(
1059+
Self::check_store_renew_unsigned(
10221060
data.len(),
10231061
|| sp_io::hashing::blake2_256(data),
10241062
context,
1025-
),
1026-
Call::<T>::renew { block, index } => {
1063+
)
1064+
}
1065+
1066+
fn check_unsigned_renew(
1067+
block: &BlockNumberFor<T>,
1068+
index: &u32,
1069+
context: CheckContext,
1070+
) -> Result<Option<ValidTransaction>, TransactionValidityError> {
10271071
let info = Self::transaction_info(*block, *index).ok_or(RENEWED_NOT_FOUND)?;
10281072
Self::check_store_renew_unsigned(
10291073
info.size as usize,
10301074
|| info.content_hash.into(),
10311075
context,
10321076
)
1033-
},
1034-
Call::<T>::remove_expired_account_authorization { who } => {
1077+
}
1078+
1079+
fn check_unsigned_remove_expired_account(
1080+
who: &T::AccountId,
1081+
context: CheckContext,
1082+
) -> Result<Option<ValidTransaction>, TransactionValidityError> {
10351083
Self::check_authorization_expired(AuthorizationScope::Account(who.clone()))?;
10361084
Ok(context.want_valid_transaction().then(|| {
10371085
ValidTransaction::with_tag_prefix(
@@ -1042,9 +1090,13 @@ pub mod pallet {
10421090
.longevity(T::RemoveExpiredAuthorizationLongevity::get())
10431091
.into()
10441092
}))
1045-
},
1046-
Call::<T>::remove_expired_preimage_authorization { content_hash } => {
1047-
Self::check_authorization_expired(AuthorizationScope::Preimage(*content_hash))?;
1093+
}
1094+
1095+
fn check_unsigned_remove_expired_preimage(
1096+
hash: &ContentHash,
1097+
context: CheckContext,
1098+
) -> Result<Option<ValidTransaction>, TransactionValidityError> {
1099+
Self::check_authorization_expired(AuthorizationScope::Preimage(*hash))?;
10481100
Ok(context.want_valid_transaction().then(|| {
10491101
ValidTransaction::with_tag_prefix(
10501102
"TransactionStorageRemoveExpiredPreimageAuthorization",
@@ -1054,7 +1106,20 @@ pub mod pallet {
10541106
.longevity(T::RemoveExpiredAuthorizationLongevity::get())
10551107
.into()
10561108
}))
1057-
},
1109+
}
1110+
1111+
fn check_unsigned(
1112+
call: &Call<T>,
1113+
context: CheckContext,
1114+
) -> Result<Option<ValidTransaction>, TransactionValidityError> {
1115+
match call {
1116+
Call::<T>::store { data } => Self::check_unsigned_store(data.as_slice(), context),
1117+
Call::<T>::renew { block, index } =>
1118+
Self::check_unsigned_renew(block, index, context),
1119+
Call::<T>::remove_expired_account_authorization { who } =>
1120+
Self::check_unsigned_remove_expired_account(who, context),
1121+
Call::<T>::remove_expired_preimage_authorization { hash } =>
1122+
Self::check_unsigned_remove_expired_preimage(hash, context),
10581123
_ => Err(InvalidTransaction::Call.into()),
10591124
}
10601125
}

pallets/transaction-storage/src/tests.rs

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@ use polkadot_sdk_frame::{
2929
prelude::{frame_system::RawOrigin, *},
3030
testing_prelude::*,
3131
};
32+
use frame_support::traits::Authorize;
3233
use sp_transaction_storage_proof::{random_chunk, registration::build_proof, CHUNK_SIZE};
34+
use sp_runtime::transaction_validity::TransactionSource;
3335

3436
type Call = super::Call<Test>;
3537
type Error = super::Error<Test>;
@@ -104,23 +106,30 @@ fn uses_preimage_authorization() {
104106
AuthorizationExtent { transactions: 1, bytes: 2002 }
105107
);
106108
let call = Call::store { data: vec![1; 2000] };
107-
assert_noop!(TransactionStorage::pre_dispatch(&call), InvalidTransaction::Payment);
109+
assert_noop!(
110+
call.authorize(TransactionSource::External).unwrap(),
111+
InvalidTransaction::Payment
112+
);
108113
let call = Call::store { data };
109-
assert_ok!(TransactionStorage::pre_dispatch(&call));
114+
assert_ok!(call.authorize(TransactionSource::External).unwrap());
110115
assert_eq!(
111116
TransactionStorage::preimage_authorization_extent(hash),
112117
AuthorizationExtent { transactions: 0, bytes: 0 }
113118
);
114-
assert_ok!(Into::<RuntimeCall>::into(call).dispatch(RuntimeOrigin::none()));
119+
assert_ok!(Into::<RuntimeCall>::into(call).dispatch(RawOrigin::Authorized.into()));
115120
run_to_block(3, || None);
116121
let call = Call::renew { block: 1, index: 0 };
117-
assert_noop!(TransactionStorage::pre_dispatch(&call), InvalidTransaction::Payment);
122+
assert_noop!(
123+
call.authorize(TransactionSource::External).unwrap(),
124+
InvalidTransaction::Payment
125+
);
118126
assert_ok!(TransactionStorage::authorize_preimage(RuntimeOrigin::root(), hash, 2000));
119-
assert_ok!(TransactionStorage::pre_dispatch(&call));
127+
assert_ok!(call.authorize(TransactionSource::External).unwrap());
120128
assert_eq!(
121129
TransactionStorage::preimage_authorization_extent(hash),
122130
AuthorizationExtent { transactions: 0, bytes: 0 }
123131
);
132+
assert_ok!(Into::<RuntimeCall>::into(call).dispatch(RawOrigin::Authorized.into()));
124133
});
125134
}
126135

@@ -292,9 +301,12 @@ fn expired_authorization_clears() {
292301
// Can't remove too early
293302
run_to_block(10, || None);
294303
let remove_call = Call::remove_expired_account_authorization { who };
295-
assert_noop!(TransactionStorage::pre_dispatch(&remove_call), AUTHORIZATION_NOT_EXPIRED);
296304
assert_noop!(
297-
Into::<RuntimeCall>::into(remove_call.clone()).dispatch(RuntimeOrigin::none()),
305+
remove_call.authorize(TransactionSource::External).unwrap(),
306+
AUTHORIZATION_NOT_EXPIRED
307+
);
308+
assert_noop!(
309+
Into::<RuntimeCall>::into(remove_call.clone()).dispatch(RawOrigin::Authorized.into()),
298310
Error::AuthorizationNotExpired,
299311
);
300312

@@ -308,8 +320,8 @@ fn expired_authorization_clears() {
308320
InvalidTransaction::Payment,
309321
);
310322
// Anyone can remove it
311-
assert_ok!(TransactionStorage::pre_dispatch(&remove_call));
312-
assert_ok!(Into::<RuntimeCall>::into(remove_call).dispatch(RuntimeOrigin::none()));
323+
assert_ok!(remove_call.authorize(TransactionSource::External).unwrap());
324+
assert_ok!(Into::<RuntimeCall>::into(remove_call).dispatch(RawOrigin::Authorized.into()));
313325
System::assert_has_event(RuntimeEvent::TransactionStorage(
314326
Event::ExpiredAccountAuthorizationRemoved { who },
315327
));

runtimes/bulletin-westend/tests/tests.rs

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,39 @@ fn construct_and_apply_extrinsic(
122122
bulletin_westend_runtime::Executive::apply_extrinsic(xt)
123123
}
124124

125+
fn construct_unsigned_extrinsic(call: RuntimeCall) -> UncheckedExtrinsic {
126+
let inner = (
127+
frame_system::AuthorizeCall::<Runtime>::new(),
128+
frame_system::CheckNonZeroSender::<Runtime>::new(),
129+
frame_system::CheckSpecVersion::<Runtime>::new(),
130+
frame_system::CheckTxVersion::<Runtime>::new(),
131+
frame_system::CheckGenesis::<Runtime>::new(),
132+
frame_system::CheckEra::<Runtime>::from(sp_runtime::generic::Era::immortal()),
133+
frame_system::CheckNonce::<Runtime>::from(0u32),
134+
frame_system::CheckWeight::<Runtime>::new(),
135+
pallet_transaction_payment::ChargeTransactionPayment::<Runtime>::from(0u128),
136+
bulletin_westend_runtime::ValidateSigned,
137+
frame_metadata_hash_extension::CheckMetadataHash::<Runtime>::new(false),
138+
);
139+
let tx_ext: TxExtension =
140+
cumulus_pallet_weight_reclaim::StorageWeightReclaim::<Runtime, _>::from(inner);
141+
UncheckedExtrinsic::new_transaction(call, tx_ext)
142+
}
143+
144+
fn construct_and_apply_unsigned_extrinsic(call: RuntimeCall) -> ApplyExtrinsicResult {
145+
let dispatch_info = call.get_dispatch_info();
146+
let xt = construct_unsigned_extrinsic(call);
147+
let xt_len = xt.encode().len();
148+
tracing::info!(
149+
"Applying unsigned extrinsic: class={:?} pays_fee={:?} weight={:?} encoded_len={} bytes",
150+
dispatch_info.class,
151+
dispatch_info.pays_fee,
152+
dispatch_info.total_weight(),
153+
xt_len
154+
);
155+
bulletin_westend_runtime::Executive::apply_extrinsic(xt)
156+
}
157+
125158
#[test]
126159
fn transaction_storage_runtime_sizes() {
127160
sp_io::TestExternalities::new(RuntimeGenesisConfig::default().build_storage().unwrap())
@@ -203,6 +236,41 @@ fn transaction_storage_runtime_sizes() {
203236
});
204237
}
205238

239+
#[test]
240+
fn transaction_storage_unsigned_preimage_store_works() {
241+
use bulletin_westend_runtime as runtime;
242+
use bulletin_westend_runtime::BuildStorage;
243+
use frame_support::assert_ok;
244+
use pallet_transaction_storage::{AuthorizationExtent, Call as TxStorageCall};
245+
246+
sp_io::TestExternalities::new(
247+
runtime::RuntimeGenesisConfig::default().build_storage().unwrap(),
248+
)
249+
.execute_with(|| {
250+
advance_block();
251+
252+
let data = vec![7u8; 2000];
253+
let hash = sp_io::hashing::blake2_256(&data);
254+
assert_ok!(runtime::TransactionStorage::authorize_preimage(
255+
RuntimeOrigin::root(),
256+
hash,
257+
data.len() as u64,
258+
));
259+
260+
let res = construct_and_apply_unsigned_extrinsic(RuntimeCall::TransactionStorage(
261+
TxStorageCall::<Runtime>::store { data },
262+
));
263+
assert_ok!(res);
264+
assert_ok!(res.unwrap());
265+
266+
assert_eq!(
267+
runtime::TransactionStorage::preimage_authorization_extent(hash),
268+
AuthorizationExtent { transactions: 0, bytes: 0 },
269+
);
270+
});
271+
}
272+
273+
206274
/// Test maximum write throughput: 8 transactions of 1 MiB each in a single block (8 MiB total).
207275
#[test]
208276
fn transaction_storage_max_throughput_per_block() {

0 commit comments

Comments
 (0)