|
1 | | -use polkadot_core_primitives::AccountId; |
| 1 | +use frame_support::traits::tokens::Precision; |
| 2 | +use sp_block_builder::runtime_decl_for_block_builder::BlockBuilderV6; |
2 | 3 | use sp_runtime::{ |
3 | 4 | generic::SignedPayload, |
4 | | - traits::{Applyable, Checkable, Lookup, Verify, StaticLookup, SignedExtension}, |
5 | | - transaction_validity::{InvalidTransaction, TransactionSource, TransactionValidityError}, |
6 | | - BuildStorage, KeyTypeId, MultiAddress, MultiSignature, |
| 5 | + transaction_validity::{ |
| 6 | + InvalidTransaction, TransactionSource, TransactionValidity, TransactionValidityError, |
| 7 | + }, |
| 8 | + BuildStorage, MultiSignature, |
7 | 9 | }; |
8 | | -use sp_transaction_pool::runtime_api::TaggedTransactionQueue; |
9 | 10 |
|
10 | 11 | use codec::Encode; |
11 | | -use sp_core::{ |
12 | | - crypto::{key_types, Pair}, |
13 | | - sr25519, |
14 | | -}; |
15 | | -use sp_keyring::sr25519::Keyring; |
| 12 | +use frame_support::traits::fungible::Balanced; |
| 13 | +use sp_core::{crypto::Pair, sr25519}; |
16 | 14 | use sp_transaction_pool::runtime_api::runtime_decl_for_tagged_transaction_queue::TaggedTransactionQueueV3; |
17 | 15 | use sugondat_kusama_runtime::{ |
18 | | - Address, Balances, Blobs, Hash, Runtime, RuntimeCall, SignedExtra, UncheckedExtrinsic, |
| 16 | + Address, Hash, MaxBlobSize, MaxBlobs, MaxTotalBlobSize, Runtime, RuntimeCall, SignedExtra, |
| 17 | + UncheckedExtrinsic, |
19 | 18 | }; |
20 | | -use sugondat_primitives::Signature; |
21 | 19 |
|
22 | 20 | use sugondat_kusama_runtime::*; |
23 | 21 |
|
24 | | -pub fn new_test_ext() -> sp_io::TestExternalities { |
| 22 | +fn new_test_ext() -> sp_io::TestExternalities { |
25 | 23 | frame_system::GenesisConfig::<Runtime>::default() |
26 | 24 | .build_storage() |
27 | 25 | .unwrap() |
28 | 26 | .into() |
29 | 27 | } |
30 | 28 |
|
31 | | -#[test] |
32 | | -fn test_validate_transaction_exceeded_max_blob_size() { |
33 | | - new_test_ext().execute_with(|| { |
34 | | - // Run a single block of the system in order to set the genesis hash. |
35 | | - // The storage of `pallet_system` is initialized to hold 0x45... as the genesis |
36 | | - // hash, so pushing a block with a different hash would overwrite it. |
37 | | - // This ensures that the `CheckEra` and `CheckGenesis` provide the same |
38 | | - // `additional_signed` payload data when constructing the transaction (here) |
39 | | - // as well as validating it in `Runtime::validate_transaction`, which internally |
40 | | - // calls `System::initialize` (prior to 1.5.0). |
41 | | - { |
42 | | - <frame_system::Pallet<Runtime>>::initialize( |
43 | | - &(frame_system::Pallet::<Runtime>::block_number() + 1), |
44 | | - &Hash::repeat_byte(1), |
45 | | - &Default::default(), |
46 | | - ); |
47 | | - <frame_system::Pallet<Runtime>>::finalize(); |
48 | | - } |
49 | | - |
50 | | - let alice_pair: sr25519::Pair = sr25519::Pair::from_string("//Alice", None) |
51 | | - .expect("Impossible generate Alice AccountId") |
52 | | - .into(); |
53 | | - |
54 | | - let alice_account_id: <Runtime as frame_system::Config>::AccountId = |
55 | | - alice_pair.public().into(); |
56 | | - let alice_address = Address::Id(alice_account_id.clone()); |
57 | | - |
58 | | - let source = TransactionSource::External; |
59 | | - |
60 | | - let max_blob_size = sugondat_kusama_runtime::MaxBlobSize::get() as usize; |
61 | | - |
62 | | - let runtime_call: RuntimeCall = pallet_sugondat_blobs::Call::submit_blob { |
63 | | - namespace_id: 0, |
64 | | - blob: vec![0; max_blob_size + 1], |
65 | | - } |
66 | | - .into(); |
67 | | - |
68 | | - let signed_extra: SignedExtra = ( |
69 | | - frame_system::CheckNonZeroSender::<Runtime>::new(), |
70 | | - frame_system::CheckSpecVersion::<Runtime>::new(), |
71 | | - frame_system::CheckTxVersion::<Runtime>::new(), |
72 | | - frame_system::CheckGenesis::<Runtime>::new(), |
73 | | - frame_system::CheckEra::<Runtime>::from(sp_runtime::generic::Era::immortal()), |
74 | | - frame_system::CheckNonce::<Runtime>::from(0), |
75 | | - frame_system::CheckWeight::<Runtime>::new(), |
76 | | - pallet_transaction_payment::ChargeTransactionPayment::<Runtime>::from(0), |
77 | | - pallet_sugondat_blobs::PrevalidateBlobs::<Runtime>::new(), |
| 29 | +fn alice_pair() -> sr25519::Pair { |
| 30 | + sr25519::Pair::from_string("//Alice", None) |
| 31 | + .expect("Impossible generate Alice AccountId") |
| 32 | + .into() |
| 33 | +} |
| 34 | + |
| 35 | +// Needed to be called inside Externalities |
| 36 | +fn prepare_environment_and_deposit_funds(account: <Runtime as frame_system::Config>::AccountId) { |
| 37 | + // Run a single block of the system in order to set the genesis hash. |
| 38 | + // The storage of `pallet_system` is initialized to hold 0x45... as the genesis |
| 39 | + // hash, so pushing a block with a different hash would overwrite it. |
| 40 | + // This ensures that the `CheckEra` and `CheckGenesis` provide the same |
| 41 | + // `additional_signed` payload data when constructing the transaction (here) |
| 42 | + // as well as validating it in `Runtime::validate_transaction`, which internally |
| 43 | + // calls `System::initialize` (prior to 1.5.0). |
| 44 | + { |
| 45 | + <frame_system::Pallet<Runtime>>::initialize( |
| 46 | + &(frame_system::Pallet::<Runtime>::block_number() + 1), |
| 47 | + &Hash::repeat_byte(1), |
| 48 | + &Default::default(), |
78 | 49 | ); |
| 50 | + <frame_system::Pallet<Runtime>>::finalize(); |
| 51 | + } |
| 52 | + |
| 53 | + // Store some funds into the account specified as argument |
| 54 | + let _ = <pallet_balances::Pallet<Runtime>>::deposit( |
| 55 | + &account, |
| 56 | + 100_000_000_000, |
| 57 | + Precision::BestEffort, |
| 58 | + ) |
| 59 | + .expect("Impossible Store Balance"); |
| 60 | +} |
| 61 | + |
| 62 | +// Needed to be called inside Externalities |
| 63 | +// |
| 64 | +// This function will only return a valid UTX if called after |
| 65 | +// `prepare_environment_and_deposit_funds`, as certain signed extension |
| 66 | +// operations require a storage preparation |
| 67 | +fn create_submit_blob_utx( |
| 68 | + signer: sr25519::Pair, |
| 69 | + namespace_id: u128, |
| 70 | + blob: Vec<u8>, |
| 71 | +) -> UncheckedExtrinsic { |
| 72 | + let signed_extra: SignedExtra = ( |
| 73 | + frame_system::CheckNonZeroSender::<Runtime>::new(), |
| 74 | + frame_system::CheckSpecVersion::<Runtime>::new(), |
| 75 | + frame_system::CheckTxVersion::<Runtime>::new(), |
| 76 | + frame_system::CheckGenesis::<Runtime>::new(), |
| 77 | + frame_system::CheckEra::<Runtime>::from(sp_runtime::generic::Era::immortal()), |
| 78 | + frame_system::CheckNonce::<Runtime>::from(0), |
| 79 | + frame_system::CheckWeight::<Runtime>::new(), |
| 80 | + pallet_transaction_payment::ChargeTransactionPayment::<Runtime>::from(0), |
| 81 | + pallet_sugondat_blobs::PrevalidateBlobs::<Runtime>::new(), |
| 82 | + ); |
| 83 | + |
| 84 | + let runtime_call: RuntimeCall = pallet_sugondat_blobs::Call::submit_blob { |
| 85 | + namespace_id: namespace_id.into(), |
| 86 | + blob, |
| 87 | + } |
| 88 | + .into(); |
79 | 89 |
|
80 | | - let raw_payload = SignedPayload::new(runtime_call.clone(), signed_extra.clone()).unwrap(); |
81 | | - let signature = raw_payload.using_encoded(|payload| { |
82 | | - let sig = alice_pair.sign(payload); |
83 | | - MultiSignature::Sr25519(sig) |
84 | | - }); |
| 90 | + let raw_payload = SignedPayload::new(runtime_call.clone(), signed_extra.clone()).unwrap(); |
| 91 | + let signature = MultiSignature::Sr25519(signer.sign(&raw_payload.encode())); |
85 | 92 |
|
86 | | - let tx = |
87 | | - UncheckedExtrinsic::new_signed(runtime_call, alice_address.clone(), signature, signed_extra); |
| 93 | + UncheckedExtrinsic::new_signed( |
| 94 | + runtime_call, |
| 95 | + Address::Id(signer.public().into()), |
| 96 | + signature, |
| 97 | + signed_extra, |
| 98 | + ) |
| 99 | +} |
| 100 | + |
| 101 | +fn test_validate_transaction(blob_size: u32, assertion: impl FnOnce(TransactionValidity)) { |
| 102 | + new_test_ext().execute_with(|| { |
| 103 | + prepare_environment_and_deposit_funds(alice_pair().public().into()); |
| 104 | + |
| 105 | + let utx = create_submit_blob_utx(alice_pair(), 0, vec![0; blob_size as usize]); |
| 106 | + |
| 107 | + let res = |
| 108 | + Runtime::validate_transaction(TransactionSource::External, utx, Hash::repeat_byte(8)); |
| 109 | + assertion(res); |
| 110 | + }); |
| 111 | +} |
| 112 | + |
| 113 | +#[test] |
| 114 | +fn test_validate_transaction_ok() { |
| 115 | + test_validate_transaction(MaxBlobSize::get(), |res| assert!(res.is_ok())) |
| 116 | +} |
88 | 117 |
|
| 118 | +#[test] |
| 119 | +fn test_validate_transaction_max_blob_size_exceeded() { |
| 120 | + test_validate_transaction(MaxBlobSize::get() + 1, |res| { |
89 | 121 | assert_eq!( |
| 122 | + res, |
90 | 123 | Err(TransactionValidityError::Invalid( |
91 | 124 | InvalidTransaction::Custom( |
92 | | - sugondat_primitives::InvalidTransactionCustomError::BlobExceedsSizeLimit as u8 |
| 125 | + sugondat_primitives::InvalidTransactionCustomError::BlobExceedsSizeLimit as u8, |
93 | 126 | ) |
94 | | - )), |
95 | | - Runtime::validate_transaction(source, tx, Hash::repeat_byte(8)) |
96 | | - ); |
| 127 | + )) |
| 128 | + ) |
| 129 | + }); |
| 130 | +} |
| 131 | + |
| 132 | +fn test_pre_dispatch(modify_storage: impl FnOnce()) { |
| 133 | + new_test_ext().execute_with(|| { |
| 134 | + modify_storage(); |
| 135 | + |
| 136 | + prepare_environment_and_deposit_funds(alice_pair().public().into()); |
| 137 | + |
| 138 | + let utx = create_submit_blob_utx(alice_pair(), 0, vec![0; 10]); |
| 139 | + |
| 140 | + assert_eq!( |
| 141 | + Runtime::apply_extrinsic(utx), |
| 142 | + Err(TransactionValidityError::Invalid( |
| 143 | + InvalidTransaction::ExhaustsResources, |
| 144 | + )) |
| 145 | + ) |
| 146 | + }); |
| 147 | +} |
| 148 | + |
| 149 | +#[test] |
| 150 | +fn test_pre_dispatch_max_blobs_exceeded() { |
| 151 | + test_pre_dispatch(|| pallet_sugondat_blobs::TotalBlobs::<Runtime>::put(MaxBlobs::get())); |
| 152 | +} |
| 153 | + |
| 154 | +#[test] |
| 155 | +fn test_pre_dispatch_max_total_blob_size_exceeded() { |
| 156 | + test_pre_dispatch(|| { |
| 157 | + pallet_sugondat_blobs::TotalBlobSize::<Runtime>::put(MaxTotalBlobSize::get()) |
97 | 158 | }); |
98 | 159 | } |
0 commit comments