git.delta.rocks / unique-network / refs/commits / 31d7a7b181c9

difftreelog

Merge commit '59ab4895e8a37bd7e512268742086167348ba9cd' into develop

Yaroslav Bolyukin2022-10-26parents: #88bdff8 #59ab489.patch.diff
in: master

29 files changed

modifiedCargo.lockdiffbeforeafterboth
5378 "pallet-structure",5378 "pallet-structure",
5379 "pallet-sudo",5379 "pallet-sudo",
5380 "pallet-template-transaction-payment",5380 "pallet-template-transaction-payment",
5381 "pallet-test-utils",
5381 "pallet-timestamp",5382 "pallet-timestamp",
5382 "pallet-transaction-payment",5383 "pallet-transaction-payment",
5383 "pallet-transaction-payment-rpc-runtime-api",5384 "pallet-transaction-payment-rpc-runtime-api",
5384 "pallet-treasury",5385 "pallet-treasury",
5385 "pallet-unique",5386 "pallet-unique",
5386 "pallet-unique-scheduler",5387 "pallet-unique-scheduler",
5388 "pallet-unique-scheduler-v2",
5387 "pallet-xcm",5389 "pallet-xcm",
5388 "parachain-info",5390 "parachain-info",
5389 "parity-scale-codec 3.2.1",5391 "parity-scale-codec 3.2.1",
6701 "up-sponsorship",6703 "up-sponsorship",
6702]6704]
6705
6706[[package]]
6707name = "pallet-test-utils"
6708version = "0.1.0"
6709dependencies = [
6710 "frame-support",
6711 "frame-system",
6712 "pallet-unique-scheduler-v2",
6713 "parity-scale-codec 3.2.1",
6714 "scale-info",
6715]
67036716
6704[[package]]6717[[package]]
6705name = "pallet-timestamp"6718name = "pallet-timestamp"
6840 "up-sponsorship",6853 "up-sponsorship",
6841]6854]
6855
6856[[package]]
6857name = "pallet-unique-scheduler-v2"
6858version = "0.1.0"
6859dependencies = [
6860 "frame-benchmarking",
6861 "frame-support",
6862 "frame-system",
6863 "log",
6864 "pallet-preimage",
6865 "parity-scale-codec 3.2.1",
6866 "scale-info",
6867 "sp-core",
6868 "sp-io",
6869 "sp-runtime",
6870 "sp-std",
6871 "substrate-test-utils",
6872]
68426873
6843[[package]]6874[[package]]
6844name = "pallet-utility"6875name = "pallet-utility"
modifiedCargo.tomldiffbeforeafterboth

no syntactic changes

addedpallets/scheduler-v2/Cargo.tomldiffbeforeafterboth

no changes

addedpallets/scheduler-v2/src/benchmarking.rsdiffbeforeafterboth

no changes

addedpallets/scheduler-v2/src/lib.rsdiffbeforeafterboth

no changes

addedpallets/scheduler-v2/src/mock.rsdiffbeforeafterboth

no changes

addedpallets/scheduler-v2/src/tests.rsdiffbeforeafterboth

no changes

addedpallets/scheduler-v2/src/weights.rsdiffbeforeafterboth

no changes

modifiedpallets/scheduler/src/benchmarking.rsdiffbeforeafterboth
5050
51const BLOCK_NUMBER: u32 = 2;51const BLOCK_NUMBER: u32 = 2;
52
53fn make_scheduled_id(src: u32) -> ScheduledId {
54 let slice_id: [u8; 4] = src.encode().try_into().unwrap();
55 let mut id: [u8; 16] = [0; 16];
56 id[..4].clone_from_slice(&slice_id);
57 id
58}
5259
53/// Add `n` named items to the schedule.60/// Add `n` named items to the schedule.
54///61///
79 false => None,86 false => None,
80 };87 };
8188
82 let slice_id: [u8; 4] = i.encode().try_into().unwrap();89 let id = make_scheduled_id(i);
83 let mut id: [u8; 16] = [0; 16];
84 id[..4].clone_from_slice(&slice_id);
85
86 let origin = frame_system::RawOrigin::Signed(caller.clone()).into();90 let origin = frame_system::RawOrigin::Signed(caller.clone()).into();
87 Scheduler::<T>::do_schedule_named(id, t, period, 0, origin, call_or_hash)?;91 Scheduler::<T>::do_schedule_named(id, t, period, 0, origin, call_or_hash)?;
202 id[..4].clone_from_slice(&slice_id);206 id[..4].clone_from_slice(&slice_id);
203 let when = BLOCK_NUMBER.into();207 let when = BLOCK_NUMBER.into();
204 let periodic = Some((T::BlockNumber::one(), 100));208 let periodic = Some((T::BlockNumber::one(), 100));
205 let priority = 0;209 let priority = None;
206 // Essentially a no-op call.210 // Essentially a no-op call.
207 let inner_call = frame_system::Call::set_storage { items: vec![] }.into();211 let inner_call = frame_system::Call::set_storage { items: vec![] }.into();
208 let call = Box::new(CallOrHashOf::<T>::Value(inner_call));212 let call = Box::new(CallOrHashOf::<T>::Value(inner_call));
220 let origin: RawOrigin<T::AccountId> = frame_system::RawOrigin::Signed(caller.clone());224 let origin: RawOrigin<T::AccountId> = frame_system::RawOrigin::Signed(caller.clone());
221 let s in 1 .. T::MaxScheduledPerBlock::get();225 let s in 1 .. T::MaxScheduledPerBlock::get();
222 let when = BLOCK_NUMBER.into();226 let when = BLOCK_NUMBER.into();
227 let idx = s - 1;
223 let id = 0.encode().try_into().unwrap_or([0; MAX_TASK_ID_LENGTH_IN_BYTES as usize]);228 let id = make_scheduled_id(idx);
224 fill_schedule::<T>(when, s, true, Some(false))?;229 fill_schedule::<T>(when, s, true, Some(false))?;
225 }: _(origin, id)230 }: _(origin, id)
226 verify {231 verify {
230 );235 );
231 // Removed schedule is NONE236 // Removed schedule is NONE
232 ensure!(237 ensure!(
233 Agenda::<T>::get(when)[0].is_none(),238 Agenda::<T>::get(when)[idx as usize].is_none(),
234 "didn't remove from schedule"239 "didn't remove from schedule"
235 );240 );
236 }241 }
242
243 change_named_priority {
244 let origin: RawOrigin<T::AccountId> = frame_system::RawOrigin::Root;
245 let s in 1 .. T::MaxScheduledPerBlock::get();
246 let when = BLOCK_NUMBER.into();
247 let idx = s - 1;
248 let id = make_scheduled_id(idx);
249 let priority = 42;
250 fill_schedule::<T>(when, s, true, Some(false))?;
251 }: _(origin, id, priority)
252 verify {
253 ensure!(
254 Agenda::<T>::get(when)[idx as usize].clone().unwrap().priority == priority,
255 "didn't change the priority"
256 );
257 }
237258
238 impl_benchmark_test_suite!(Scheduler, crate::mock::new_test_ext(), crate::mock::Test);259 impl_benchmark_test_suite!(Scheduler, crate::mock::new_test_ext(), crate::mock::Test);
239}260}
modifiedpallets/scheduler/src/lib.rsdiffbeforeafterboth
8787
88use frame_support::{88use frame_support::{
89 dispatch::{DispatchError, DispatchResult, Dispatchable, Parameter, GetDispatchInfo},89 dispatch::{
90 DispatchError, DispatchResult, Dispatchable, UnfilteredDispatchable, Parameter,
91 GetDispatchInfo,
92 },
90 traits::{93 traits::{
91 schedule::{self, DispatchTime, MaybeHashed},94 schedule::{self, DispatchTime, MaybeHashed},
97100
98pub use weights::WeightInfo;101pub use weights::WeightInfo;
99102
100/// Just a simple index for naming period tasks.
101pub type PeriodicIndex = u32;
102/// The location of a scheduled task that can be used to remove it.103/// The location of a scheduled task that can be used to remove it.
103pub type TaskAddress<BlockNumber> = (BlockNumber, u32);104pub type TaskAddress<BlockNumber> = (BlockNumber, u32);
104pub const MAX_TASK_ID_LENGTH_IN_BYTES: u8 = 16;105pub const MAX_TASK_ID_LENGTH_IN_BYTES: u8 = 16;
105106
106type ScheduledId = [u8; MAX_TASK_ID_LENGTH_IN_BYTES as usize];107pub type ScheduledId = [u8; MAX_TASK_ID_LENGTH_IN_BYTES as usize];
107pub type CallOrHashOf<T> =108pub type CallOrHashOf<T> =
108 MaybeHashed<<T as Config>::RuntimeCall, <T as frame_system::Config>::Hash>;109 MaybeHashed<<T as Config>::RuntimeCall, <T as frame_system::Config>::Hash>;
109110
137pub type Scheduled<Call, BlockNumber, PalletsOrigin, AccountId> =138pub type Scheduled<Call, BlockNumber, PalletsOrigin, AccountId> =
138 ScheduledV3<Call, BlockNumber, PalletsOrigin, AccountId>;139 ScheduledV3<Call, BlockNumber, PalletsOrigin, AccountId>;
140
141pub enum ScheduledEnsureOriginSuccess<AccountId> {
142 Root,
143 Signed(AccountId),
144}
139145
140#[cfg(feature = "runtime-benchmarks")]146#[cfg(feature = "runtime-benchmarks")]
141mod preimage_provider {147mod preimage_provider {
194 dispatch::PostDispatchInfo,200 dispatch::PostDispatchInfo,
195 pallet_prelude::*,201 pallet_prelude::*,
196 traits::{schedule::LookupError, PreimageProvider},202 traits::{
203 schedule::{LookupError, LOWEST_PRIORITY},
204 PreimageProvider,
205 },
197 };206 };
198 use frame_system::pallet_prelude::*;207 use frame_system::pallet_prelude::*;
227 + Dispatchable<236 + Dispatchable<
228 RuntimeOrigin = <Self as Config>::RuntimeOrigin,237 RuntimeOrigin = <Self as Config>::RuntimeOrigin,
229 PostInfo = PostDispatchInfo,238 PostInfo = PostDispatchInfo,
230 > + GetDispatchInfo239 > + UnfilteredDispatchable<RuntimeOrigin = <Self as system::Config>::RuntimeOrigin>
240 + GetDispatchInfo
231 + From<system::Call<Self>>;241 + From<system::Call<Self>>;
232242
237247
238 /// Required origin to schedule or cancel calls.248 /// Required origin to schedule or cancel calls.
239 type ScheduleOrigin: EnsureOrigin<<Self as system::Config>::RuntimeOrigin>;249 type ScheduleOrigin: EnsureOrigin<
250 <Self as system::Config>::RuntimeOrigin,
251 Success = ScheduledEnsureOriginSuccess<Self::AccountId>,
252 >;
253
254 /// Required origin to set/change calls' priority.
255 type PrioritySetOrigin: EnsureOrigin<<Self as system::Config>::RuntimeOrigin>;
240256
241 /// Compare the privileges of origins.257 /// Compare the privileges of origins.
242 ///258 ///
287303
288 /// Resolve the call dispatch, including any post-dispatch operations.304 /// Resolve the call dispatch, including any post-dispatch operations.
289 fn dispatch_call(305 fn dispatch_call(
290 signer: T::AccountId,306 signer: Option<T::AccountId>,
291 function: <T as Config>::RuntimeCall,307 function: <T as Config>::RuntimeCall,
292 ) -> Result<308 ) -> Result<
293 Result<PostDispatchInfo, DispatchErrorWithPostInfo<PostDispatchInfo>>,309 Result<PostDispatchInfo, DispatchErrorWithPostInfo<PostDispatchInfo>>,
319 Scheduled { when: T::BlockNumber, index: u32 },335 Scheduled { when: T::BlockNumber, index: u32 },
320 /// Canceled some task.336 /// Canceled some task.
321 Canceled { when: T::BlockNumber, index: u32 },337 Canceled { when: T::BlockNumber, index: u32 },
338 /// Scheduled task's priority has changed
339 PriorityChanged {
340 when: T::BlockNumber,
341 index: u32,
342 priority: schedule::Priority,
343 },
322 /// Dispatched some task.344 /// Dispatched some task.
323 Dispatched {345 Dispatched {
324 task: TaskAddress<T::BlockNumber>,346 task: TaskAddress<T::BlockNumber>,
371393
372 let mut total_weight: Weight = T::WeightInfo::on_initialize(0);394 let mut total_weight: Weight = T::WeightInfo::on_initialize(0);
373 for (order, (index, mut s)) in queued.into_iter().enumerate() {395 for (order, (index, mut s)) in queued.into_iter().enumerate() {
374 let named = if let Some(ref id) = s.maybe_id {396 let named = s.maybe_id.is_some();
375 Lookup::<T>::remove(id);
376 true
377 } else {
378 false
379 };
380397
381 let (call, maybe_completed) = s.call.resolved::<T::PreimageProvider>();398 let (call, maybe_completed) = s.call.resolved::<T::PreimageProvider>();
382 s.call = call;399 s.call = call;
399 Lookup::<T>::insert(id, (until, index as u32));416 Lookup::<T>::insert(id, (until, index as u32));
400 }417 }
401 Agenda::<T>::append(until, Some(s));418 Agenda::<T>::append(until, Some(s));
402 }419 } else if let Some(ref id) = s.maybe_id {
420 Lookup::<T>::remove(id);
421 }
403 continue;422 continue;
404 }423 }
405 };424 };
439 continue;458 continue;
440 }459 }
441460
442 let sender = ensure_signed(461 let scheduled_origin =
443 <<T as Config>::RuntimeOrigin as From<T::PalletsOrigin>>::from(462 <<T as Config>::RuntimeOrigin as From<T::PalletsOrigin>>::from(
444 s.origin.clone(),463 s.origin.clone(),
445 )464 );
446 .into(),465 let ensured_origin = T::ScheduleOrigin::ensure_origin(scheduled_origin.into());
447 )466
448 .unwrap();
449
450 // // if call have id it was be reserved
451 // if s.maybe_id.is_some() {
452 // let _ = T::CallExecutor::pay_for_call(
453 // s.maybe_id.unwrap(),
454 // sender.clone(),
455 // call.clone(),
456 // );
457 // }
458
459 // Execute transaction via chain default pipeline
460 // That means dispatch will be processed like any user's extrinsic e.g. transaction fees will be taken
461 let r = T::CallExecutor::dispatch_call(sender, call.clone());467 let r = match ensured_origin {
468 Ok(ScheduledEnsureOriginSuccess::Root) => {
469 Ok(call.dispatch_bypass_filter(frame_system::RawOrigin::Root.into()))
470 }
471 Ok(ScheduledEnsureOriginSuccess::Signed(sender)) => {
472 // Execute transaction via chain default pipeline
473 // That means dispatch will be processed like any user's extrinsic e.g. transaction fees will be taken
474 T::CallExecutor::dispatch_call(Some(sender), call.clone())
475 }
476 Err(e) => Ok(Err(e.into())),
477 };
462478
463 let mut actual_call_weight: Weight = item_weight;479 let mut actual_call_weight: Weight = item_weight;
464 let result: Result<_, DispatchError> = match r {480 let result: Result<_, DispatchError> = match r {
494 s.maybe_periodic = None;510 s.maybe_periodic = None;
495 }511 }
496 let wake = now + period;512 let wake = now + period;
513 let is_canceled;
514
497 // If scheduled is named, place its information in `Lookup`515 // If scheduled is named, place its information in `Lookup`
498 if let Some(ref id) = s.maybe_id {516 if let Some(ref id) = s.maybe_id {
517 is_canceled = Lookup::<T>::get(id).is_none();
499 let wake_index = Agenda::<T>::decode_len(wake).unwrap_or(0);518 let wake_index = Agenda::<T>::decode_len(wake).unwrap_or(0);
519
520 if !is_canceled {
500 Lookup::<T>::insert(id, (wake, wake_index as u32));521 Lookup::<T>::insert(id, (wake, wake_index as u32));
522 }
501 }523 } else {
524 is_canceled = false;
525 }
526
527 if !is_canceled {
502 Agenda::<T>::append(wake, Some(s));528 Agenda::<T>::append(wake, Some(s));
529 }
503 }530 } else if let Some(ref id) = s.maybe_id {
531 Lookup::<T>::remove(id);
532 }
504 }533 }
505 // Total weight should be 0, because the transaction is already paid for534 total_weight
506 Weight::zero()
507 }535 }
508 }536 }
509537
516 id: ScheduledId,544 id: ScheduledId,
517 when: T::BlockNumber,545 when: T::BlockNumber,
518 maybe_periodic: Option<schedule::Period<T::BlockNumber>>,546 maybe_periodic: Option<schedule::Period<T::BlockNumber>>,
519 priority: schedule::Priority,547 priority: Option<schedule::Priority>,
520 call: Box<CallOrHashOf<T>>,548 call: Box<CallOrHashOf<T>>,
521 ) -> DispatchResult {549 ) -> DispatchResult {
522 T::ScheduleOrigin::ensure_origin(origin.clone())?;550 T::ScheduleOrigin::ensure_origin(origin.clone())?;
551
552 if priority.is_some() {
553 T::PrioritySetOrigin::ensure_origin(origin.clone())?;
554 }
555
523 let origin = <T as Config>::RuntimeOrigin::from(origin);556 let origin = <T as Config>::RuntimeOrigin::from(origin);
524 Self::do_schedule_named(557 Self::do_schedule_named(
525 id,558 id,
526 DispatchTime::At(when),559 DispatchTime::At(when),
527 maybe_periodic,560 maybe_periodic,
528 priority,561 priority.unwrap_or(LOWEST_PRIORITY),
529 origin.caller().clone(),562 origin.caller().clone(),
530 *call,563 *call,
531 )?;564 )?;
552 id: ScheduledId,585 id: ScheduledId,
553 after: T::BlockNumber,586 after: T::BlockNumber,
554 maybe_periodic: Option<schedule::Period<T::BlockNumber>>,587 maybe_periodic: Option<schedule::Period<T::BlockNumber>>,
555 priority: schedule::Priority,588 priority: Option<schedule::Priority>,
556 call: Box<CallOrHashOf<T>>,589 call: Box<CallOrHashOf<T>>,
557 ) -> DispatchResult {590 ) -> DispatchResult {
558 T::ScheduleOrigin::ensure_origin(origin.clone())?;591 T::ScheduleOrigin::ensure_origin(origin.clone())?;
592
593 if priority.is_some() {
594 T::PrioritySetOrigin::ensure_origin(origin.clone())?;
595 }
596
559 let origin = <T as Config>::RuntimeOrigin::from(origin);597 let origin = <T as Config>::RuntimeOrigin::from(origin);
560 Self::do_schedule_named(598 Self::do_schedule_named(
561 id,599 id,
562 DispatchTime::After(after),600 DispatchTime::After(after),
563 maybe_periodic,601 maybe_periodic,
564 priority,602 priority.unwrap_or(LOWEST_PRIORITY),
565 origin.caller().clone(),603 origin.caller().clone(),
566 *call,604 *call,
567 )?;605 )?;
568 Ok(())606 Ok(())
569 }607 }
608
609 #[pallet::weight(<T as Config>::WeightInfo::change_named_priority(T::MaxScheduledPerBlock::get()))]
610 pub fn change_named_priority(
611 origin: OriginFor<T>,
612 id: ScheduledId,
613 priority: schedule::Priority,
614 ) -> DispatchResult {
615 T::PrioritySetOrigin::ensure_origin(origin.clone())?;
616 let origin = <T as Config>::RuntimeOrigin::from(origin);
617 Self::do_change_named_priority(origin.caller().clone(), id, priority)
618 }
570 }619 }
571}620}
572621
720 })769 })
721 }770 }
771
772 fn do_change_named_priority(
773 origin: T::PalletsOrigin,
774 id: ScheduledId,
775 priority: schedule::Priority,
776 ) -> DispatchResult {
777 match Lookup::<T>::get(id) {
778 Some((when, index)) => {
779 let i = index as usize;
780 Agenda::<T>::try_mutate(when, |agenda| {
781 if let Some(Some(s)) = agenda.get_mut(i) {
782 if matches!(
783 T::OriginPrivilegeCmp::cmp_privilege(&origin, &s.origin),
784 Some(Ordering::Less) | None
785 ) {
786 return Err(BadOrigin.into());
787 }
788
789 s.priority = priority;
790 Self::deposit_event(Event::PriorityChanged {
791 when,
792 index,
793 priority,
794 });
795 }
796 Ok(())
797 })
798 }
799 None => Err(Error::<T>::NotFound.into()),
800 }
801 }
722}802}
723803
modifiedpallets/scheduler/src/weights.rsdiffbeforeafterboth
3//! Autogenerated weights for pallet_unique_scheduler3//! Autogenerated weights for pallet_unique_scheduler
4//!4//!
5//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev5//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
6//! DATE: 2022-08-15, STEPS: `50`, REPEAT: 80, LOW RANGE: `[]`, HIGH RANGE: `[]`6//! DATE: 2022-09-14, STEPS: `50`, REPEAT: 80, LOW RANGE: `[]`, HIGH RANGE: `[]`
7//! EXECUTION: None, WASM-EXECUTION: Compiled, CHAIN: None, DB CACHE: 10247//! EXECUTION: None, WASM-EXECUTION: Compiled, CHAIN: None, DB CACHE: 1024
88
9// Executed Command:9// Executed Command:
26#![cfg_attr(rustfmt, rustfmt_skip)]26#![cfg_attr(rustfmt, rustfmt_skip)]
27#![allow(unused_parens)]27#![allow(unused_parens)]
28#![allow(unused_imports)]28#![allow(unused_imports)]
29#![allow(missing_docs)]
29#![allow(clippy::unnecessary_cast)]30#![allow(clippy::unnecessary_cast)]
3031
31use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}};32use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}};
44 fn on_initialize_resolved(s: u32, ) -> Weight;45 fn on_initialize_resolved(s: u32, ) -> Weight;
45 fn schedule_named(s: u32, ) -> Weight;46 fn schedule_named(s: u32, ) -> Weight;
46 fn cancel_named(s: u32, ) -> Weight;47 fn cancel_named(s: u32, ) -> Weight;
48 fn change_named_priority(s: u32, ) -> Weight;
47}49}
4850
49/// Weights for pallet_unique_scheduler using the Substrate node and recommended hardware.51/// Weights for pallet_unique_scheduler using the Substrate node and recommended hardware.
53 // Storage: System Account (r:1 w:1)55 // Storage: System Account (r:1 w:1)
54 // Storage: System AllExtrinsicsLen (r:1 w:1)56 // Storage: System AllExtrinsicsLen (r:1 w:1)
55 // Storage: System BlockWeight (r:1 w:1)57 // Storage: System BlockWeight (r:1 w:1)
58 // Storage: Configuration WeightToFeeCoefficientOverride (r:1 w:0)
59 // Storage: TransactionPayment NextFeeMultiplier (r:1 w:0)
56 // Storage: Scheduler Lookup (r:0 w:1)60 // Storage: Scheduler Lookup (r:1 w:1)
57 fn on_initialize_periodic_named_resolved(s: u32, ) -> Weight {61 fn on_initialize_periodic_named_resolved(s: u32, ) -> Weight {
58 Weight::from_ref_time(26_641_000)62 Weight::from_ref_time(26_641_000)
59 // Standard Error: 9_00063 // Standard Error: 9_000
67 // Storage: System Account (r:1 w:1)71 // Storage: System Account (r:1 w:1)
68 // Storage: System AllExtrinsicsLen (r:1 w:1)72 // Storage: System AllExtrinsicsLen (r:1 w:1)
69 // Storage: System BlockWeight (r:1 w:1)73 // Storage: System BlockWeight (r:1 w:1)
74 // Storage: Configuration WeightToFeeCoefficientOverride (r:1 w:0)
75 // Storage: TransactionPayment NextFeeMultiplier (r:1 w:0)
70 // Storage: Scheduler Lookup (r:0 w:1)76 // Storage: Scheduler Lookup (r:0 w:1)
71 fn on_initialize_named_resolved(s: u32, ) -> Weight {77 fn on_initialize_named_resolved(s: u32, ) -> Weight {
72 Weight::from_ref_time(23_941_000)78 Weight::from_ref_time(23_941_000)
80 // Storage: System Account (r:1 w:1)86 // Storage: System Account (r:1 w:1)
81 // Storage: System AllExtrinsicsLen (r:1 w:1)87 // Storage: System AllExtrinsicsLen (r:1 w:1)
82 // Storage: System BlockWeight (r:1 w:1)88 // Storage: System BlockWeight (r:1 w:1)
89 // Storage: Configuration WeightToFeeCoefficientOverride (r:1 w:0)
90 // Storage: TransactionPayment NextFeeMultiplier (r:1 w:0)
83 // Storage: Scheduler Lookup (r:0 w:1)91 // Storage: Scheduler Lookup (r:1 w:1)
84 fn on_initialize_periodic(s: u32, ) -> Weight {92 fn on_initialize_periodic(s: u32, ) -> Weight {
85 Weight::from_ref_time(24_858_000)93 Weight::from_ref_time(24_858_000)
86 // Standard Error: 7_00094 // Standard Error: 7_000
94 // Storage: System Account (r:1 w:1)102 // Storage: System Account (r:1 w:1)
95 // Storage: System AllExtrinsicsLen (r:1 w:1)103 // Storage: System AllExtrinsicsLen (r:1 w:1)
96 // Storage: System BlockWeight (r:1 w:1)104 // Storage: System BlockWeight (r:1 w:1)
105 // Storage: Configuration WeightToFeeCoefficientOverride (r:1 w:0)
106 // Storage: TransactionPayment NextFeeMultiplier (r:1 w:0)
97 // Storage: Scheduler Lookup (r:0 w:1)107 // Storage: Scheduler Lookup (r:1 w:1)
98 fn on_initialize_periodic_resolved(s: u32, ) -> Weight {108 fn on_initialize_periodic_resolved(s: u32, ) -> Weight {
99 Weight::from_ref_time(25_515_000)109 Weight::from_ref_time(25_515_000)
100 // Standard Error: 14_000110 // Standard Error: 14_000
118 // Storage: System Account (r:1 w:1)128 // Storage: System Account (r:1 w:1)
119 // Storage: System AllExtrinsicsLen (r:1 w:1)129 // Storage: System AllExtrinsicsLen (r:1 w:1)
120 // Storage: System BlockWeight (r:1 w:1)130 // Storage: System BlockWeight (r:1 w:1)
131 // Storage: Configuration WeightToFeeCoefficientOverride (r:1 w:0)
132 // Storage: TransactionPayment NextFeeMultiplier (r:1 w:0)
121 // Storage: Scheduler Lookup (r:0 w:1)133 // Storage: Scheduler Lookup (r:0 w:1)
122 fn on_initialize_named_aborted(s: u32, ) -> Weight {134 fn on_initialize_named_aborted(s: u32, ) -> Weight {
123 Weight::from_ref_time(25_552_000)135 Weight::from_ref_time(25_552_000)
141 // Storage: System Account (r:1 w:1)153 // Storage: System Account (r:1 w:1)
142 // Storage: System AllExtrinsicsLen (r:1 w:1)154 // Storage: System AllExtrinsicsLen (r:1 w:1)
143 // Storage: System BlockWeight (r:1 w:1)155 // Storage: System BlockWeight (r:1 w:1)
156 // Storage: Configuration WeightToFeeCoefficientOverride (r:1 w:0)
157 // Storage: TransactionPayment NextFeeMultiplier (r:1 w:0)
144 // Storage: Scheduler Lookup (r:0 w:1)158 // Storage: Scheduler Lookup (r:0 w:1)
145 fn on_initialize(s: u32, ) -> Weight {159 fn on_initialize(s: u32, ) -> Weight {
146 Weight::from_ref_time(24_482_000)160 Weight::from_ref_time(24_482_000)
154 // Storage: System Account (r:1 w:1)168 // Storage: System Account (r:1 w:1)
155 // Storage: System AllExtrinsicsLen (r:1 w:1)169 // Storage: System AllExtrinsicsLen (r:1 w:1)
156 // Storage: System BlockWeight (r:1 w:1)170 // Storage: System BlockWeight (r:1 w:1)
171 // Storage: Configuration WeightToFeeCoefficientOverride (r:1 w:0)
172 // Storage: TransactionPayment NextFeeMultiplier (r:1 w:0)
157 // Storage: Scheduler Lookup (r:0 w:1)173 // Storage: Scheduler Lookup (r:0 w:1)
158 fn on_initialize_resolved(s: u32, ) -> Weight {174 fn on_initialize_resolved(s: u32, ) -> Weight {
159 Weight::from_ref_time(25_187_000)175 Weight::from_ref_time(25_187_000)
181 .saturating_add(T::DbWeight::get().reads(2 as u64))197 .saturating_add(T::DbWeight::get().reads(2 as u64))
182 .saturating_add(T::DbWeight::get().writes(2 as u64))198 .saturating_add(T::DbWeight::get().writes(2 as u64))
183 }199 }
200 // Storage: Scheduler Lookup (r:1 w:1)
201 // Storage: Scheduler Agenda (r:1 w:1)
202 fn change_named_priority(s: u32, ) -> Weight {
203 Weight::from_ref_time(8_642_000)
204 // Standard Error: 0
205 .saturating_add(Weight::from_ref_time(431_000).saturating_mul(s as u64))
206 .saturating_add(T::DbWeight::get().reads(2 as u64))
207 .saturating_add(T::DbWeight::get().writes(2 as u64))
208 }
184}209}
185210
186// For backwards compatibility and tests211// For backwards compatibility and tests
189 // Storage: System Account (r:1 w:1)214 // Storage: System Account (r:1 w:1)
190 // Storage: System AllExtrinsicsLen (r:1 w:1)215 // Storage: System AllExtrinsicsLen (r:1 w:1)
191 // Storage: System BlockWeight (r:1 w:1)216 // Storage: System BlockWeight (r:1 w:1)
217 // Storage: Configuration WeightToFeeCoefficientOverride (r:1 w:0)
218 // Storage: TransactionPayment NextFeeMultiplier (r:1 w:0)
192 // Storage: Scheduler Lookup (r:0 w:1)219 // Storage: Scheduler Lookup (r:1 w:1)
193 fn on_initialize_periodic_named_resolved(s: u32, ) -> Weight {220 fn on_initialize_periodic_named_resolved(s: u32, ) -> Weight {
194 Weight::from_ref_time(26_641_000)221 Weight::from_ref_time(26_641_000)
195 // Standard Error: 9_000222 // Standard Error: 9_000
203 // Storage: System Account (r:1 w:1)230 // Storage: System Account (r:1 w:1)
204 // Storage: System AllExtrinsicsLen (r:1 w:1)231 // Storage: System AllExtrinsicsLen (r:1 w:1)
205 // Storage: System BlockWeight (r:1 w:1)232 // Storage: System BlockWeight (r:1 w:1)
233 // Storage: Configuration WeightToFeeCoefficientOverride (r:1 w:0)
234 // Storage: TransactionPayment NextFeeMultiplier (r:1 w:0)
206 // Storage: Scheduler Lookup (r:0 w:1)235 // Storage: Scheduler Lookup (r:0 w:1)
207 fn on_initialize_named_resolved(s: u32, ) -> Weight {236 fn on_initialize_named_resolved(s: u32, ) -> Weight {
208 Weight::from_ref_time(23_941_000)237 Weight::from_ref_time(23_941_000)
216 // Storage: System Account (r:1 w:1)245 // Storage: System Account (r:1 w:1)
217 // Storage: System AllExtrinsicsLen (r:1 w:1)246 // Storage: System AllExtrinsicsLen (r:1 w:1)
218 // Storage: System BlockWeight (r:1 w:1)247 // Storage: System BlockWeight (r:1 w:1)
248 // Storage: Configuration WeightToFeeCoefficientOverride (r:1 w:0)
249 // Storage: TransactionPayment NextFeeMultiplier (r:1 w:0)
219 // Storage: Scheduler Lookup (r:0 w:1)250 // Storage: Scheduler Lookup (r:1 w:1)
220 fn on_initialize_periodic(s: u32, ) -> Weight {251 fn on_initialize_periodic(s: u32, ) -> Weight {
221 Weight::from_ref_time(24_858_000)252 Weight::from_ref_time(24_858_000)
222 // Standard Error: 7_000253 // Standard Error: 7_000
230 // Storage: System Account (r:1 w:1)261 // Storage: System Account (r:1 w:1)
231 // Storage: System AllExtrinsicsLen (r:1 w:1)262 // Storage: System AllExtrinsicsLen (r:1 w:1)
232 // Storage: System BlockWeight (r:1 w:1)263 // Storage: System BlockWeight (r:1 w:1)
264 // Storage: Configuration WeightToFeeCoefficientOverride (r:1 w:0)
265 // Storage: TransactionPayment NextFeeMultiplier (r:1 w:0)
233 // Storage: Scheduler Lookup (r:0 w:1)266 // Storage: Scheduler Lookup (r:1 w:1)
234 fn on_initialize_periodic_resolved(s: u32, ) -> Weight {267 fn on_initialize_periodic_resolved(s: u32, ) -> Weight {
235 Weight::from_ref_time(25_515_000)268 Weight::from_ref_time(25_515_000)
236 // Standard Error: 14_000269 // Standard Error: 14_000
254 // Storage: System Account (r:1 w:1)287 // Storage: System Account (r:1 w:1)
255 // Storage: System AllExtrinsicsLen (r:1 w:1)288 // Storage: System AllExtrinsicsLen (r:1 w:1)
256 // Storage: System BlockWeight (r:1 w:1)289 // Storage: System BlockWeight (r:1 w:1)
290 // Storage: Configuration WeightToFeeCoefficientOverride (r:1 w:0)
291 // Storage: TransactionPayment NextFeeMultiplier (r:1 w:0)
257 // Storage: Scheduler Lookup (r:0 w:1)292 // Storage: Scheduler Lookup (r:0 w:1)
258 fn on_initialize_named_aborted(s: u32, ) -> Weight {293 fn on_initialize_named_aborted(s: u32, ) -> Weight {
259 Weight::from_ref_time(25_552_000)294 Weight::from_ref_time(25_552_000)
277 // Storage: System Account (r:1 w:1)312 // Storage: System Account (r:1 w:1)
278 // Storage: System AllExtrinsicsLen (r:1 w:1)313 // Storage: System AllExtrinsicsLen (r:1 w:1)
279 // Storage: System BlockWeight (r:1 w:1)314 // Storage: System BlockWeight (r:1 w:1)
315 // Storage: Configuration WeightToFeeCoefficientOverride (r:1 w:0)
316 // Storage: TransactionPayment NextFeeMultiplier (r:1 w:0)
280 // Storage: Scheduler Lookup (r:0 w:1)317 // Storage: Scheduler Lookup (r:0 w:1)
281 fn on_initialize(s: u32, ) -> Weight {318 fn on_initialize(s: u32, ) -> Weight {
282 Weight::from_ref_time(24_482_000)319 Weight::from_ref_time(24_482_000)
290 // Storage: System Account (r:1 w:1)327 // Storage: System Account (r:1 w:1)
291 // Storage: System AllExtrinsicsLen (r:1 w:1)328 // Storage: System AllExtrinsicsLen (r:1 w:1)
292 // Storage: System BlockWeight (r:1 w:1)329 // Storage: System BlockWeight (r:1 w:1)
330 // Storage: Configuration WeightToFeeCoefficientOverride (r:1 w:0)
331 // Storage: TransactionPayment NextFeeMultiplier (r:1 w:0)
293 // Storage: Scheduler Lookup (r:0 w:1)332 // Storage: Scheduler Lookup (r:0 w:1)
294 fn on_initialize_resolved(s: u32, ) -> Weight {333 fn on_initialize_resolved(s: u32, ) -> Weight {
295 Weight::from_ref_time(25_187_000)334 Weight::from_ref_time(25_187_000)
318 .saturating_add(RocksDbWeight::get().writes(2 as u64))357 .saturating_add(RocksDbWeight::get().writes(2 as u64))
319 }358 }
359
360 // Storage: Scheduler Lookup (r:1 w:1)
361 // Storage: Scheduler Agenda (r:1 w:1)
362 fn change_named_priority(s: u32, ) -> Weight {
363 Weight::from_ref_time(8_642_000)
364 // Standard Error: 0
365 .saturating_add(Weight::from_ref_time(431_000).saturating_mul(s as u64))
366 .saturating_add(RocksDbWeight::get().reads(2 as u64))
367 .saturating_add(RocksDbWeight::get().writes(2 as u64))
368 }
320}369}
321370
modifiedruntime/common/config/mod.rsdiffbeforeafterboth
22pub mod substrate;22pub mod substrate;
23pub mod xcm;23pub mod xcm;
24
25#[cfg(feature = "pallet-test-utils")]
26pub mod test_pallets;
2427
modifiedruntime/common/config/pallets/scheduler.rsdiffbeforeafterboth
15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
1616
17use frame_support::{traits::PrivilegeCmp, weights::Weight, parameter_types};17use frame_support::{
18 traits::{PrivilegeCmp, EnsureOrigin},
19 weights::Weight,
20 parameter_types,
21};
18use frame_system::EnsureSigned;22use frame_system::{EnsureRoot, RawOrigin};
19use sp_runtime::Perbill;23use sp_runtime::Perbill;
20use sp_std::cmp::Ordering;24use core::cmp::Ordering;
25use codec::Decode;
21use crate::{26use crate::{
22 runtime_common::{scheduler::SchedulerPaymentExecutor, config::substrate::RuntimeBlockWeights},27 runtime_common::{scheduler::SchedulerPaymentExecutor, config::substrate::RuntimeBlockWeights},
23 Runtime, Call, Event, Origin, OriginCaller, Balances,28 Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, OriginCaller, Balances,
24};29};
30use pallet_unique_scheduler_v2::ScheduledEnsureOriginSuccess;
25use up_common::types::AccountId;31use up_common::types::AccountId;
2632
27parameter_types! {33parameter_types! {
33 pub const Preimage: Option<u32> = Some(10);39 pub const Preimage: Option<u32> = Some(10);
34}40}
3541
36/// Used the compare the privilege of an origin inside the scheduler.
37pub struct OriginPrivilegeCmp;42pub struct EnsureSignedOrRoot<AccountId>(sp_std::marker::PhantomData<AccountId>);
3843impl<O: Into<Result<RawOrigin<AccountId>, O>> + From<RawOrigin<AccountId>>, AccountId: Decode>
44 EnsureOrigin<O> for EnsureSignedOrRoot<AccountId>
45{
46 type Success = ScheduledEnsureOriginSuccess<AccountId>;
47 fn try_origin(o: O) -> Result<Self::Success, O> {
48 o.into().and_then(|o| match o {
49 RawOrigin::Root => Ok(ScheduledEnsureOriginSuccess::Root),
50 RawOrigin::Signed(who) => Ok(ScheduledEnsureOriginSuccess::Signed(who)),
51 r => Err(O::from(r)),
52 })
53 }
54}
55
56pub struct EqualOrRootOnly;
39impl PrivilegeCmp<OriginCaller> for OriginPrivilegeCmp {57impl PrivilegeCmp<OriginCaller> for EqualOrRootOnly {
40 fn cmp_privilege(_left: &OriginCaller, _right: &OriginCaller) -> Option<Ordering> {58 fn cmp_privilege(left: &OriginCaller, right: &OriginCaller) -> Option<Ordering> {
59 use RawOrigin::*;
60
61 let left = left.clone().try_into().ok()?;
62 let right = right.clone().try_into().ok()?;
63
64 match (left, right) {
41 Some(Ordering::Equal)65 (Root, Root) => Some(Ordering::Equal),
66 (Root, _) => Some(Ordering::Greater),
67 (_, Root) => Some(Ordering::Less),
68 lr @ _ => (lr.0 == lr.1).then(|| Ordering::Equal),
69 }
42 }70 }
43}71}
72
73// impl pallet_unique_scheduler::Config for Runtime {
74// type RuntimeEvent = RuntimeEvent;
75// type RuntimeOrigin = RuntimeOrigin;
76// type Currency = Balances;
77// type PalletsOrigin = OriginCaller;
78// type RuntimeCall = RuntimeCall;
79// type MaximumWeight = MaximumSchedulerWeight;
80// type ScheduleOrigin = EnsureSignedOrRoot<AccountId>;
81// type PrioritySetOrigin = EnsureRoot<AccountId>;
82// type MaxScheduledPerBlock = MaxScheduledPerBlock;
83// type WeightInfo = ();
84// type CallExecutor = SchedulerPaymentExecutor;
85// type OriginPrivilegeCmp = EqualOrRootOnly;
86// type PreimageProvider = ();
87// type NoPreimagePostponement = NoPreimagePostponement;
88// }
4489
45impl pallet_unique_scheduler::Config for Runtime {90impl pallet_unique_scheduler_v2::Config for Runtime {
46 type RuntimeEvent = RuntimeEvent;91 type RuntimeEvent = RuntimeEvent;
47 type RuntimeOrigin = RuntimeOrigin;92 type RuntimeOrigin = RuntimeOrigin;
48 type Currency = Balances;
49 type PalletsOrigin = OriginCaller;93 type PalletsOrigin = OriginCaller;
50 type RuntimeCall = RuntimeCall;94 type RuntimeCall = RuntimeCall;
51 type MaximumWeight = MaximumSchedulerWeight;95 type MaximumWeight = MaximumSchedulerWeight;
52 type ScheduleOrigin = EnsureSigned<AccountId>;96 type ScheduleOrigin = EnsureSignedOrRoot<AccountId>;
97 type OriginPrivilegeCmp = EqualOrRootOnly;
53 type MaxScheduledPerBlock = MaxScheduledPerBlock;98 type MaxScheduledPerBlock = MaxScheduledPerBlock;
54 type WeightInfo = ();99 type WeightInfo = ();
55 type CallExecutor = SchedulerPaymentExecutor;100 type Preimages = ();
56 type OriginPrivilegeCmp = OriginPrivilegeCmp;101 type CallExecutor = SchedulerPaymentExecutor;
57 type PreimageProvider = ();102 type PrioritySetOrigin = EnsureRoot<AccountId>;
58 type NoPreimagePostponement = NoPreimagePostponement;
59}103}
60104
addedruntime/common/config/test_pallets.rsdiffbeforeafterboth

no changes

modifiedruntime/common/construct_runtime/mod.rsdiffbeforeafterboth
94 EvmTransactionPayment: pallet_evm_transaction_payment::{Pallet} = 152,94 EvmTransactionPayment: pallet_evm_transaction_payment::{Pallet} = 152,
95 EvmMigration: pallet_evm_migration::{Pallet, Call, Storage} = 153,95 EvmMigration: pallet_evm_migration::{Pallet, Call, Storage} = 153,
96
97 #[runtimes(opal)]
98 Scheduler: pallet_unique_scheduler_v2::{Pallet, Call, Storage, Event<T>} = 154,
99
100 #[runtimes(opal)]
101 TestUtils: pallet_test_utils = 255,
96 }102 }
97 }103 }
98 }104 }
modifiedruntime/common/scheduler.rsdiffbeforeafterboth
1616
17use frame_support::{17use frame_support::{
18 traits::NamedReservableCurrency,18 traits::NamedReservableCurrency,
19 weights::{GetDispatchInfo, PostDispatchInfo, DispatchInfo},19 dispatch::{GetDispatchInfo, PostDispatchInfo, DispatchInfo},
20};20};
21use sp_runtime::{21use sp_runtime::{
22 traits::{Dispatchable, Applyable, Member},22 traits::{Dispatchable, Applyable, Member},
23 generic::Era,23 generic::Era,
24 transaction_validity::TransactionValidityError,24 transaction_validity::TransactionValidityError,
25 DispatchErrorWithPostInfo, DispatchError,25 DispatchErrorWithPostInfo, DispatchError,
26};26};
27use codec::Encode;
27use crate::{Runtime, Call, Origin, Balances, ChargeTransactionPayment};28use crate::{Runtime, RuntimeCall, RuntimeOrigin, Balances};
28use up_common::types::{AccountId, Balance};29use up_common::types::{AccountId, Balance};
29use fp_self_contained::SelfContainedCall;30use fp_self_contained::SelfContainedCall;
30use pallet_unique_scheduler::DispatchCall;31use pallet_unique_scheduler_v2::DispatchCall;
32use pallet_transaction_payment::ChargeTransactionPayment;
33
34// type SponsorshipChargeTransactionPayment =
35// pallet_charge_transaction::ChargeTransactionPayment<Runtime>;
3136
32/// The SignedExtension to the basic transaction logic.37/// The SignedExtension to the basic transaction logic.
33pub type SignedExtraScheduler = (38pub type SignedExtraScheduler = (
36 frame_system::CheckEra<Runtime>,41 frame_system::CheckEra<Runtime>,
37 frame_system::CheckNonce<Runtime>,42 frame_system::CheckNonce<Runtime>,
38 frame_system::CheckWeight<Runtime>,43 frame_system::CheckWeight<Runtime>,
44 ChargeTransactionPayment<Runtime>,
39);45);
4046
41fn get_signed_extras(from: <Runtime as frame_system::Config>::AccountId) -> SignedExtraScheduler {47fn get_signed_extras(from: <Runtime as frame_system::Config>::AccountId) -> SignedExtraScheduler {
47 from,53 from,
48 )),54 )),
49 frame_system::CheckWeight::<Runtime>::new(),55 frame_system::CheckWeight::<Runtime>::new(),
50 // sponsoring transaction logic56 ChargeTransactionPayment::<Runtime>::from(0),
51 // pallet_charge_transaction::ChargeTransactionPayment::<Runtime>::new(0),
52 )57 )
53}58}
5459
55pub struct SchedulerPaymentExecutor;60pub struct SchedulerPaymentExecutor;
5661
57impl<T: frame_system::Config + pallet_unique_scheduler::Config, SelfContainedSignedInfo>62impl<T: frame_system::Config + pallet_unique_scheduler_v2::Config, SelfContainedSignedInfo>
58 DispatchCall<T, SelfContainedSignedInfo> for SchedulerPaymentExecutor63 DispatchCall<T, SelfContainedSignedInfo> for SchedulerPaymentExecutor
59where64where
60 <T as frame_system::Config>::Call: Member65 <T as frame_system::Config>::RuntimeCall: Member
61 + Dispatchable<Origin = Origin, Info = DispatchInfo>66 + Dispatchable<RuntimeOrigin = RuntimeOrigin, Info = DispatchInfo>
62 + SelfContainedCall<SignedInfo = SelfContainedSignedInfo>67 + SelfContainedCall<SignedInfo = SelfContainedSignedInfo>
63 + GetDispatchInfo68 + GetDispatchInfo
64 + From<frame_system::Call<Runtime>>,69 + From<frame_system::Call<Runtime>>,
65 SelfContainedSignedInfo: Send + Sync + 'static,70 SelfContainedSignedInfo: Send + Sync + 'static,
66 Call: From<<T as frame_system::Config>::Call>71 RuntimeCall: From<<T as frame_system::Config>::RuntimeCall>
67 + From<<T as pallet_unique_scheduler::Config>::Call>72 + From<<T as pallet_unique_scheduler_v2::Config>::RuntimeCall>
68 + SelfContainedCall<SignedInfo = SelfContainedSignedInfo>,73 + SelfContainedCall<SignedInfo = SelfContainedSignedInfo>,
69 sp_runtime::AccountId32: From<<T as frame_system::Config>::AccountId>,74 sp_runtime::AccountId32: From<<T as frame_system::Config>::AccountId>,
70{75{
71 fn dispatch_call(76 fn dispatch_call(
72 signer: <T as frame_system::Config>::AccountId,77 signer: Option<<T as frame_system::Config>::AccountId>,
73 call: <T as pallet_unique_scheduler::Config>::Call,78 call: <T as pallet_unique_scheduler_v2::Config>::RuntimeCall,
74 ) -> Result<79 ) -> Result<
75 Result<PostDispatchInfo, DispatchErrorWithPostInfo<PostDispatchInfo>>,80 Result<PostDispatchInfo, DispatchErrorWithPostInfo<PostDispatchInfo>>,
76 TransactionValidityError,81 TransactionValidityError,
77 > {82 > {
78 let dispatch_info = call.get_dispatch_info();83 let dispatch_info = call.get_dispatch_info();
84 let len = call.encoded_size();
85
79 let extrinsic = fp_self_contained::CheckedExtrinsic::<86 let signed = match signer {
80 AccountId,
81 Call,
82 SignedExtraScheduler,
83 SelfContainedSignedInfo,
84 > {
85 signed: fp_self_contained::CheckedSignature::<87 Some(signer) => fp_self_contained::CheckedSignature::Signed(
86 AccountId,
87 SignedExtraScheduler,
88 SelfContainedSignedInfo,
89 >::Signed(signer.clone().into(), get_signed_extras(signer.into())),88 signer.clone().into(),
90 function: call.into(),89 get_signed_extras(signer.into()),
90 ),
91 None => fp_self_contained::CheckedSignature::Unsigned,
91 };92 };
93
94 let extrinsic = fp_self_contained::CheckedExtrinsic::<
95 AccountId,
96 RuntimeCall,
97 SignedExtraScheduler,
98 SelfContainedSignedInfo,
99 > {
100 signed,
101 function: call.into(),
102 };
92103
93 extrinsic.apply::<Runtime>(&dispatch_info, 0)104 extrinsic.apply::<Runtime>(&dispatch_info, len)
94 }105 }
95
96 fn reserve_balance(
97 id: [u8; 16],
98 sponsor: <T as frame_system::Config>::AccountId,
99 call: <T as pallet_unique_scheduler::Config>::Call,
100 count: u32,
101 ) -> Result<(), DispatchError> {
102 let dispatch_info = call.get_dispatch_info();
103 let weight: Balance = ChargeTransactionPayment::traditional_fee(0, &dispatch_info, 0)
104 .saturating_mul(count.into());
105
106 <Balances as NamedReservableCurrency<AccountId>>::reserve_named(
107 &id,
108 &(sponsor.into()),
109 weight,
110 )
111 }
112
113 fn pay_for_call(
114 id: [u8; 16],
115 sponsor: <T as frame_system::Config>::AccountId,
116 call: <T as pallet_unique_scheduler::Config>::Call,
117 ) -> Result<u128, DispatchError> {
118 let dispatch_info = call.get_dispatch_info();
119 let weight: Balance = ChargeTransactionPayment::traditional_fee(0, &dispatch_info, 0);
120 Ok(
121 <Balances as NamedReservableCurrency<AccountId>>::unreserve_named(
122 &id,
123 &(sponsor.into()),
124 weight,
125 ),
126 )
127 }
128
129 fn cancel_reserve(
130 id: [u8; 16],
131 sponsor: <T as frame_system::Config>::AccountId,
132 ) -> Result<u128, DispatchError> {
133 Ok(
134 <Balances as NamedReservableCurrency<AccountId>>::unreserve_named(
135 &id,
136 &(sponsor.into()),
137 u128::MAX,
138 ),
139 )
140 }
141}106}
107
108// impl<T: frame_system::Config + pallet_unique_scheduler::Config, SelfContainedSignedInfo>
109// DispatchCall<T, SelfContainedSignedInfo> for SchedulerPaymentExecutor
110// where
111// <T as frame_system::Config>::Call: Member
112// + Dispatchable<Origin = Origin, Info = DispatchInfo>
113// + SelfContainedCall<SignedInfo = SelfContainedSignedInfo>
114// + GetDispatchInfo
115// + From<frame_system::Call<Runtime>>,
116// SelfContainedSignedInfo: Send + Sync + 'static,
117// Call: From<<T as frame_system::Config>::Call>
118// + From<<T as pallet_unique_scheduler::Config>::Call>
119// + SelfContainedCall<SignedInfo = SelfContainedSignedInfo>,
120// sp_runtime::AccountId32: From<<T as frame_system::Config>::AccountId>,
121// {
122// fn dispatch_call(
123// signer: Option<<T as frame_system::Config>::AccountId>,
124// call: <T as pallet_unique_scheduler::Config>::Call,
125// ) -> Result<
126// Result<PostDispatchInfo, DispatchErrorWithPostInfo<PostDispatchInfo>>,
127// TransactionValidityError,
128// > {
129// let dispatch_info = call.get_dispatch_info();
130// let len = call.encoded_size();
131
132// let signed = match signer {
133// Some(signer) => fp_self_contained::CheckedSignature::Signed(
134// signer.clone().into(),
135// get_signed_extras(signer.into()),
136// ),
137// None => fp_self_contained::CheckedSignature::Unsigned,
138// };
139
140// let extrinsic = fp_self_contained::CheckedExtrinsic::<
141// AccountId,
142// Call,
143// SignedExtraScheduler,
144// SelfContainedSignedInfo,
145// > {
146// signed,
147// function: call.into(),
148// };
149
150// extrinsic.apply::<Runtime>(&dispatch_info, len)
151// }
152
153// fn reserve_balance(
154// id: [u8; 16],
155// sponsor: <T as frame_system::Config>::AccountId,
156// call: <T as pallet_unique_scheduler::Config>::Call,
157// count: u32,
158// ) -> Result<(), DispatchError> {
159// let dispatch_info = call.get_dispatch_info();
160// let weight: Balance =
161// SponsorshipChargeTransactionPayment::traditional_fee(0, &dispatch_info, 0)
162// .saturating_mul(count.into());
163
164// <Balances as NamedReservableCurrency<AccountId>>::reserve_named(
165// &id,
166// &(sponsor.into()),
167// weight,
168// )
169// }
170
171// fn pay_for_call(
172// id: [u8; 16],
173// sponsor: <T as frame_system::Config>::AccountId,
174// call: <T as pallet_unique_scheduler::Config>::Call,
175// ) -> Result<u128, DispatchError> {
176// let dispatch_info = call.get_dispatch_info();
177// let weight: Balance =
178// SponsorshipChargeTransactionPayment::traditional_fee(0, &dispatch_info, 0);
179// Ok(
180// <Balances as NamedReservableCurrency<AccountId>>::unreserve_named(
181// &id,
182// &(sponsor.into()),
183// weight,
184// ),
185// )
186// }
187
188// fn cancel_reserve(
189// id: [u8; 16],
190// sponsor: <T as frame_system::Config>::AccountId,
191// ) -> Result<u128, DispatchError> {
192// Ok(
193// <Balances as NamedReservableCurrency<AccountId>>::unreserve_named(
194// &id,
195// &(sponsor.into()),
196// u128::MAX,
197// ),
198// )
199// }
200// }
142201
modifiedruntime/opal/Cargo.tomldiffbeforeafterboth
42 'pallet-inflation/runtime-benchmarks',42 'pallet-inflation/runtime-benchmarks',
43 'pallet-app-promotion/runtime-benchmarks',43 'pallet-app-promotion/runtime-benchmarks',
44 'pallet-unique-scheduler/runtime-benchmarks',44 'pallet-unique-scheduler/runtime-benchmarks',
45 'pallet-unique-scheduler-v2/runtime-benchmarks',
45 'pallet-xcm/runtime-benchmarks',46 'pallet-xcm/runtime-benchmarks',
46 'sp-runtime/runtime-benchmarks',47 'sp-runtime/runtime-benchmarks',
47 'xcm-builder/runtime-benchmarks',48 'xcm-builder/runtime-benchmarks',
140 'pallet-proxy-rmrk-equip/std',141 'pallet-proxy-rmrk-equip/std',
141 'pallet-unique/std',142 'pallet-unique/std',
142 'pallet-unique-scheduler/std',143 'pallet-unique-scheduler/std',
144 'pallet-unique-scheduler-v2/std',
143 'pallet-charge-transaction/std',145 'pallet-charge-transaction/std',
144 'up-data-structs/std',146 'up-data-structs/std',
145 'sp-api/std',147 'sp-api/std',
168 "orml-traits/std",170 "orml-traits/std",
169 "pallet-foreign-assets/std",171 "pallet-foreign-assets/std",
172
173 'pallet-test-utils?/std',
170]174]
171limit-testing = ['pallet-unique/limit-testing', 'up-data-structs/limit-testing']175limit-testing = ['pallet-unique/limit-testing', 'up-data-structs/limit-testing']
172opal-runtime = ['refungible', 'rmrk', 'app-promotion', 'foreign-assets']176opal-runtime = ['refungible', 'scheduler', 'rmrk', 'app-promotion', 'foreign-assets', 'pallet-test-utils']
173177
174refungible = []178refungible = []
175scheduler = []179scheduler = []
470pallet-proxy-rmrk-equip = { default-features = false, path = "../../pallets/proxy-rmrk-equip", package = "pallet-rmrk-equip" }474pallet-proxy-rmrk-equip = { default-features = false, path = "../../pallets/proxy-rmrk-equip", package = "pallet-rmrk-equip" }
471pallet-unique-scheduler = { path = '../../pallets/scheduler', default-features = false }475pallet-unique-scheduler = { path = '../../pallets/scheduler', default-features = false }
472pallet-charge-transaction = { git = "https://github.com/uniquenetwork/pallet-sponsoring", branch = "polkadot-v0.9.30", package = "pallet-template-transaction-payment", default-features = false, version = "3.0.0" }476pallet-charge-transaction = { git = "https://github.com/uniquenetwork/pallet-sponsoring", branch = "polkadot-v0.9.30", package = "pallet-template-transaction-payment", default-features = false, version = "3.0.0" }
477pallet-unique-scheduler-v2 = { path = '../../pallets/scheduler-v2', default-features = false }
473pallet-evm-migration = { path = '../../pallets/evm-migration', default-features = false }478pallet-evm-migration = { path = '../../pallets/evm-migration', default-features = false }
474pallet-evm-contract-helpers = { path = '../../pallets/evm-contract-helpers', default-features = false }479pallet-evm-contract-helpers = { path = '../../pallets/evm-contract-helpers', default-features = false }
475pallet-evm-transaction-payment = { path = '../../pallets/evm-transaction-payment', default-features = false }480pallet-evm-transaction-payment = { path = '../../pallets/evm-transaction-payment', default-features = false }
483up-sponsorship = { default-features = false, git = "https://github.com/uniquenetwork/pallet-sponsoring", branch = 'polkadot-v0.9.30' }488up-sponsorship = { default-features = false, git = "https://github.com/uniquenetwork/pallet-sponsoring", branch = 'polkadot-v0.9.30' }
484pallet-foreign-assets = { default-features = false, path = "../../pallets/foreign-assets" }489pallet-foreign-assets = { default-features = false, path = "../../pallets/foreign-assets" }
490
491################################################################################
492# Test dependencies
493
494pallet-test-utils = { optional = true, default-features = false, path = "../../test-pallets/utils" }
485495
486################################################################################496################################################################################
487# Other Dependencies497# Other Dependencies
addedtest-pallets/utils/Cargo.lockdiffbeforeafterboth

no changes

addedtest-pallets/utils/Cargo.tomldiffbeforeafterboth

no changes

addedtest-pallets/utils/src/lib.rsdiffbeforeafterboth

no changes

deletedtests/src/.outdated/eth/scheduling.test.tsdiffbeforeafterboth

no changes

deletedtests/src/.outdated/scheduler.test.tsdiffbeforeafterboth

no changes

addedtests/src/eth/scheduling.test.tsdiffbeforeafterboth

no changes

modifiedtests/src/eth/util/playgrounds/unique.dev.tsdiffbeforeafterboth
352 }352 }
353} 353}
354
355export class EthPropertyGroup extends EthGroupBase {
356 property(key: string, value: string): EthProperty {
357 return [
358 key,
359 '0x'+Buffer.from(value).toString('hex'),
360 ];
361 }
362}
363export type EthUniqueHelperConstructor = new (...args: any[]) => EthUniqueHelper;354export type EthUniqueHelperConstructor = new (...args: any[]) => EthUniqueHelper;
364355
365export class EthCrossAccountGroup extends EthGroupBase {356export class EthCrossAccountGroup extends EthGroupBase {
modifiedtests/src/pallet-presence.test.tsdiffbeforeafterboth
62 const chain = await helper.callRpc('api.rpc.system.chain', []);62 const chain = await helper.callRpc('api.rpc.system.chain', []);
6363
64 const refungible = 'refungible';64 const refungible = 'refungible';
65 // const scheduler = 'scheduler';65 const scheduler = 'scheduler';
66 const foreignAssets = 'foreignassets';66 const foreignAssets = 'foreignassets';
67 const rmrkPallets = ['rmrkcore', 'rmrkequip'];67 const rmrkPallets = ['rmrkcore', 'rmrkequip'];
68 const appPromotion = 'apppromotion';68 const appPromotion = 'apppromotion';
69 const testUtils = 'testutils';
6970
70 if (chain.eq('OPAL by UNIQUE')) {71 if (chain.eq('OPAL by UNIQUE')) {
71 requiredPallets.push(72 requiredPallets.push(
72 refungible,73 refungible,
73 // scheduler,74 // scheduler,
74 foreignAssets,75 foreignAssets,
75 appPromotion,76 appPromotion,
77 testUtils,
78 scheduler,
76 ...rmrkPallets,79 ...rmrkPallets,
77 );80 );
78 } else if (chain.eq('QUARTZ by UNIQUE')) {81 } else if (chain.eq('QUARTZ by UNIQUE')) {
addedtests/src/scheduler.test.tsdiffbeforeafterboth

no changes

modifiedtests/src/util/index.tsdiffbeforeafterboth
95 NFT = 'nonfungible',95 NFT = 'nonfungible',
96 Scheduler = 'scheduler',96 Scheduler = 'scheduler',
97 AppPromotion = 'apppromotion',97 AppPromotion = 'apppromotion',
98 TestUtils = 'testutils',
98}99}
99100
100export function requirePalletsOrSkip(test: Context, helper: DevUniqueHelper, requiredPallets: string[]) {101export function requirePalletsOrSkip(test: Context, helper: DevUniqueHelper, requiredPallets: string[]) {
modifiedtests/src/util/playgrounds/unique.dev.tsdiffbeforeafterboth
8import * as defs from '../../interfaces/definitions';8import * as defs from '../../interfaces/definitions';
9import {IKeyringPair} from '@polkadot/types/types';9import {IKeyringPair} from '@polkadot/types/types';
10import {EventRecord} from '@polkadot/types/interfaces';10import {EventRecord} from '@polkadot/types/interfaces';
11import {ICrossAccountId} from './types';11import {ICrossAccountId, TSigner} from './types';
12import {FrameSystemEventRecord} from '@polkadot/types/lookup';12import {FrameSystemEventRecord} from '@polkadot/types/lookup';
13import {VoidFn} from '@polkadot/api/types';
14import {Pallets} from '..';
1315
14export class SilentLogger {16export class SilentLogger {
15 log(_msg: any, _level: any): void { }17 log(_msg: any, _level: any): void { }
63 arrange: ArrangeGroup;65 arrange: ArrangeGroup;
64 wait: WaitGroup;66 wait: WaitGroup;
65 admin: AdminGroup;67 admin: AdminGroup;
68 testUtils: TestUtilGroup;
6669
67 constructor(logger: { log: (msg: any, level: any) => void, level: any }, options: {[key: string]: any} = {}) {70 constructor(logger: { log: (msg: any, level: any) => void, level: any }, options: {[key: string]: any} = {}) {
68 options.helperBase = options.helperBase ?? DevUniqueHelper;71 options.helperBase = options.helperBase ?? DevUniqueHelper;
71 this.arrange = new ArrangeGroup(this);74 this.arrange = new ArrangeGroup(this);
72 this.wait = new WaitGroup(this);75 this.wait = new WaitGroup(this);
73 this.admin = new AdminGroup(this);76 this.admin = new AdminGroup(this);
77 this.testUtils = new TestUtilGroup(this);
74 }78 }
7579
76 async connect(wsEndpoint: string, _listeners?: any): Promise<void> {80 async connect(wsEndpoint: string, _listeners?: any): Promise<void> {
154class ArrangeGroup {158class ArrangeGroup {
155 helper: DevUniqueHelper;159 helper: DevUniqueHelper;
160
161 scheduledIdSlider = 0;
156162
157 constructor(helper: DevUniqueHelper) {163 constructor(helper: DevUniqueHelper) {
158 this.helper = helper;164 this.helper = helper;
298 return encodeAddress(address);304 return encodeAddress(address);
299 }305 }
306
307 async makeScheduledIds(num: number): Promise<string[]> {
308 await this.helper.wait.noScheduledTasks();
309
310 function makeId(slider: number) {
311 const scheduledIdSize = 64;
312 const hexId = slider.toString(16);
313 const prefixSize = scheduledIdSize - hexId.length;
314
315 const scheduledId = '0x' + '0'.repeat(prefixSize) + hexId;
316
317 return scheduledId;
318 }
319
320 const ids = [];
321 for (let i = 0; i < num; i++) {
322 ids.push(makeId(this.scheduledIdSlider));
323 this.scheduledIdSlider += 1;
324 }
325
326 return ids;
327 }
328
329 async makeScheduledId(): Promise<string> {
330 return (await this.makeScheduledIds(1))[0];
331 }
332
333 async captureEvents(eventSection: string, eventMethod: string): Promise<EventCapture> {
334 const capture = new EventCapture(this.helper, eventSection, eventMethod);
335 await capture.startCapture();
336
337 return capture;
338 }
300}339}
301340
302class MoonbeamAccountGroup {341class MoonbeamAccountGroup {
389 });428 });
390 }429 }
430
431 async noScheduledTasks() {
432 const api = this.helper.getApi();
433
434 // eslint-disable-next-line no-async-promise-executor
435 const promise = new Promise<void>(async resolve => {
436 const unsubscribe = await api.rpc.chain.subscribeNewHeads(async () => {
437 const areThereScheduledTasks = await api.query.scheduler.lookup.entries();
438
439 if(areThereScheduledTasks.length == 0) {
440 unsubscribe();
441 resolve();
442 }
443 });
444 });
445
446 return promise;
447 }
391448
392 async event(maxBlocksToWait: number, eventSection: string, eventMethod: string) {449 async event(maxBlocksToWait: number, eventSection: string, eventMethod: string) {
393 // eslint-disable-next-line no-async-promise-executor450 // eslint-disable-next-line no-async-promise-executor
424 }480 }
425}481}
482
483class TestUtilGroup {
484 helper: DevUniqueHelper;
485
486 constructor(helper: DevUniqueHelper) {
487 this.helper = helper;
488 }
489
490 async enable() {
491 if (this.helper.fetchMissingPalletNames([Pallets.TestUtils]).length != 0) {
492 return;
493 }
494
495 const signer = this.helper.util.fromSeed('//Alice');
496 await this.helper.getSudo<DevUniqueHelper>().executeExtrinsic(signer, 'api.tx.testUtils.enable', [], true);
497 }
498
499 async setTestValue(signer: TSigner, testVal: number) {
500 await this.helper.executeExtrinsic(signer, 'api.tx.testUtils.setTestValue', [testVal], true);
501 }
502
503 async incTestValue(signer: TSigner) {
504 await this.helper.executeExtrinsic(signer, 'api.tx.testUtils.incTestValue', [], true);
505 }
506
507 async setTestValueAndRollback(signer: TSigner, testVal: number) {
508 await this.helper.executeExtrinsic(signer, 'api.tx.testUtils.setTestValueAndRollback', [testVal], true);
509 }
510
511 async testValue() {
512 return (await this.helper.callRpc('api.query.testUtils.testValue', [])).toNumber();
513 }
514
515 async justTakeFee(signer: TSigner) {
516 await this.helper.executeExtrinsic(signer, 'api.tx.testUtils.justTakeFee', [], true);
517 }
518
519 async selfCancelingInc(signer: TSigner, scheduledId: string, maxTestVal: number) {
520 await this.helper.executeExtrinsic(signer, 'api.tx.testUtils.selfCancelingInc', [scheduledId, maxTestVal], true);
521 }
522}
523
524class EventCapture {
525 helper: DevUniqueHelper;
526 eventSection: string;
527 eventMethod: string;
528 events: EventRecord[] = [];
529 unsubscribe: VoidFn | null = null;
530
531 constructor(
532 helper: DevUniqueHelper,
533 eventSection: string,
534 eventMethod: string,
535 ) {
536 this.helper = helper;
537 this.eventSection = eventSection;
538 this.eventMethod = eventMethod;
539 }
540
541 async startCapture() {
542 this.stopCapture();
543 this.unsubscribe = (await this.helper.getApi().query.system.events((eventRecords: FrameSystemEventRecord[]) => {
544 const newEvents = eventRecords.filter(r => {
545 return r.event.section == this.eventSection && r.event.method == this.eventMethod;
546 });
547
548 this.events.push(...newEvents);
549 })) as any;
550 }
551
552 stopCapture() {
553 if (this.unsubscribe !== null) {
554 this.unsubscribe();
555 }
556 }
557
558 extractCapturedEvents() {
559 return this.events;
560 }
561}
426562
427class AdminGroup {563class AdminGroup {
428 helper: UniqueHelper;564 helper: UniqueHelper;
modifiedtests/src/util/playgrounds/unique.tsdiffbeforeafterboth
39 MoonbeamAssetInfo,39 MoonbeamAssetInfo,
40 DemocracyStandardAccountVote,40 DemocracyStandardAccountVote,
41} from './types';41} from './types';
42import {RuntimeDispatchInfo} from '@polkadot/types/interfaces';
4243
43export class CrossAccountId implements ICrossAccountId {44export class CrossAccountId implements ICrossAccountId {
44 Substrate?: TSubstrateAccount;45 Substrate?: TSubstrateAccount;
561 });562 });
562 }563 }
564
565 async getPaymentInfo(signer: TSigner, tx: any, len: number | null) {
566 const api = this.getApi();
567 const signingInfo = await api.derive.tx.signingInfo(signer.address);
568
569 // We need to sign the tx because
570 // unsigned transactions does not have an inclusion fee
571 tx.sign(signer, {
572 blockHash: api.genesisHash,
573 genesisHash: api.genesisHash,
574 runtimeVersion: api.runtimeVersion,
575 nonce: signingInfo.nonce,
576 });
577
578 if (len === null) {
579 return (await this.callRpc('api.rpc.payment.queryInfo', [tx.toHex()])) as RuntimeDispatchInfo;
580 } else {
581 return (await api.call.transactionPaymentApi.queryInfo(tx, len)) as RuntimeDispatchInfo;
582 }
583 }
563584
564 constructApiCall(apiCall: string, params: any[]) {585 constructApiCall(apiCall: string, params: any[]) {
565 if(!apiCall.startsWith('api.')) throw Error(`Invalid api call: ${apiCall}`);586 if(!apiCall.startsWith('api.')) throw Error(`Invalid api call: ${apiCall}`);
933 return this.helper.util.findCollectionInEvents(result.result.events, collectionId, 'unique', 'CollectionAdminRemoved');954 return this.helper.util.findCollectionInEvents(result.result.events, collectionId, 'unique', 'CollectionAdminRemoved');
934 }955 }
935956
936 /**957 /**
937 * Check if user is in allow list.958 * Check if user is in allow list.
938 * 959 *
939 * @param collectionId ID of collection960 * @param collectionId ID of collection
940 * @param user Account to check961 * @param user Account to check
941 * @example await getAdmins(1)962 * @example await getAdmins(1)
942 * @returns is user in allow list963 * @returns is user in allow list
943 */964 */
944 async allowed(collectionId: number, user: ICrossAccountId): Promise<boolean> {965 async allowed(collectionId: number, user: ICrossAccountId): Promise<boolean> {
945 return (await this.helper.callRpc('api.rpc.unique.allowed', [collectionId, user])).toJSON();966 return (await this.helper.callRpc('api.rpc.unique.allowed', [collectionId, user])).toJSON();
946 }967 }
1043 return this.helper.util.findCollectionInEvents(result.result.events, collectionId, 'common', 'CollectionPropertySet');1064 return this.helper.util.findCollectionInEvents(result.result.events, collectionId, 'common', 'CollectionPropertySet');
1044 }1065 }
10451066
1046 /**1067 /**
1047 * Get collection properties.1068 * Get collection properties.
1048 * 1069 *
1049 * @param collectionId ID of collection1070 * @param collectionId ID of collection
1050 * @param propertyKeys optionally filter the returned properties to only these keys1071 * @param propertyKeys optionally filter the returned properties to only these keys
1051 * @example getProperties(1219, ['location', 'date', 'time', 'isParadise']);1072 * @example getProperties(1219, ['location', 'date', 'time', 'isParadise']);
1052 * @returns array of key-value pairs1073 * @returns array of key-value pairs
1053 */1074 */
1054 async getProperties(collectionId: number, propertyKeys?: string[] | null): Promise<IProperty[]> {1075 async getProperties(collectionId: number, propertyKeys?: string[] | null): Promise<IProperty[]> {
1055 return (await this.helper.callRpc('api.rpc.unique.collectionProperties', [collectionId, propertyKeys])).toHuman();1076 return (await this.helper.callRpc('api.rpc.unique.collectionProperties', [collectionId, propertyKeys])).toHuman();
1056 }1077 }
1295 return this.helper.util.findCollectionInEvents(result.result.events, collectionId, 'common', 'PropertyPermissionSet');1316 return this.helper.util.findCollectionInEvents(result.result.events, collectionId, 'common', 'PropertyPermissionSet');
1296 }1317 }
12971318
1298 /**1319 /**
1299 * Get token property permissions.1320 * Get token property permissions.
1300 * 1321 *
1301 * @param collectionId ID of collection1322 * @param collectionId ID of collection
1302 * @param propertyKeys optionally filter the returned property permissions to only these keys1323 * @param propertyKeys optionally filter the returned property permissions to only these keys
1303 * @example getPropertyPermissions(1219, ['location', 'date', 'time', 'isParadise']);1324 * @example getPropertyPermissions(1219, ['location', 'date', 'time', 'isParadise']);
1304 * @returns array of key-permission pairs1325 * @returns array of key-permission pairs
1305 */1326 */
1306 async getPropertyPermissions(collectionId: number, propertyKeys: string[] | null = null): Promise<ITokenPropertyPermission[]> {1327 async getPropertyPermissions(collectionId: number, propertyKeys: string[] | null = null): Promise<ITokenPropertyPermission[]> {
1307 return (await this.helper.callRpc('api.rpc.unique.propertyPermissions', [collectionId, ...(propertyKeys === null ? [] : [propertyKeys])])).toHuman();1328 return (await this.helper.callRpc('api.rpc.unique.propertyPermissions', [collectionId, ...(propertyKeys === null ? [] : [propertyKeys])])).toHuman();
1308 }1329 }
1327 return this.helper.util.findCollectionInEvents(result.result.events, collectionId, 'common', 'TokenPropertySet');1348 return this.helper.util.findCollectionInEvents(result.result.events, collectionId, 'common', 'TokenPropertySet');
1328 }1349 }
13291350
1330 /**1351 /**
1331 * Get properties, metadata assigned to a token.1352 * Get properties, metadata assigned to a token.
1332 * 1353 *
1333 * @param collectionId ID of collection1354 * @param collectionId ID of collection
1334 * @param tokenId ID of token1355 * @param tokenId ID of token
1335 * @param propertyKeys optionally filter the returned properties to only these keys1356 * @param propertyKeys optionally filter the returned properties to only these keys
1336 * @example getTokenProperties(1219, ['location', 'date', 'time', 'isParadise']);1357 * @example getTokenProperties(1219, ['location', 'date', 'time', 'isParadise']);
1337 * @returns array of key-value pairs1358 * @returns array of key-value pairs
1338 */1359 */
1339 async getTokenProperties(collectionId: number, tokenId: number, propertyKeys?: string[] | null): Promise<IProperty[]> {1360 async getTokenProperties(collectionId: number, tokenId: number, propertyKeys?: string[] | null): Promise<IProperty[]> {
1340 return (await this.helper.callRpc('api.rpc.unique.tokenProperties', [collectionId, tokenId, propertyKeys])).toHuman();1361 return (await this.helper.callRpc('api.rpc.unique.tokenProperties', [collectionId, tokenId, propertyKeys])).toHuman();
1341 }1362 }
2284 return this.subBalanceGroup.transferToSubstrate(signer, address, amount);2305 return this.subBalanceGroup.transferToSubstrate(signer, address, amount);
2285 }2306 }
2307
2308 async forceTransferToSubstrate(signer: TSigner, from: TSubstrateAccount, to: TSubstrateAccount, amount: bigint | string): Promise<boolean> {
2309 const result = await this.helper.executeExtrinsic(signer, 'api.tx.balances.forceTransfer', [from, to, amount], true);
2310
2311 let transfer = {from: null, to: null, amount: 0n} as any;
2312 result.result.events.forEach(({event: {data, method, section}}) => {
2313 if ((section === 'balances') && (method === 'Transfer')) {
2314 transfer = {
2315 from: this.helper.address.normalizeSubstrate(data[0]),
2316 to: this.helper.address.normalizeSubstrate(data[1]),
2317 amount: BigInt(data[2]),
2318 };
2319 }
2320 });
2321 let isSuccess = this.helper.address.normalizeSubstrate(from) === transfer.from;
2322 isSuccess = isSuccess && this.helper.address.normalizeSubstrate(to) === transfer.to;
2323 isSuccess = isSuccess && BigInt(amount) === transfer.amount;
2324 return isSuccess;
2325 }
2286}2326}
22872327
2288class AddressGroup extends HelperGroup<ChainHelperBase> {2328class AddressGroup extends HelperGroup<ChainHelperBase> {
2798 this.blocksNum,2838 this.blocksNum,
2799 this.options.periodic ? [this.options.periodic.period, this.options.periodic.repetitions] : null,2839 this.options.periodic ? [this.options.periodic.period, this.options.periodic.repetitions] : null,
2800 this.options.priority ?? null,2840 this.options.priority ?? null,
2801 {Value: scheduledTx},2841 scheduledTx,
2802 ],2842 ],
2803 expectSuccess,2843 expectSuccess,
2804 );2844 );