Skip to content
This repository has been archived by the owner on Feb 21, 2024. It is now read-only.

Commit

Permalink
bound vecs (#112)
Browse files Browse the repository at this point in the history
* chore: add rust-toolchain

* fix: bound PlannedExecutions with MAX_SLOTS

for now bound with const, could be an associated type in config

* fix: bound AllowedSources with T::MaxAllowedSources

* chore: remove unused

* feat: add ParameterBound

just the necessary trait bounds from Parameter

* fix: bound PlannedExecutions with T::MaxSlots

* fix: bound AdvertisementRestriction::allowed_consumers with T::MaxAllowedConsumers
  • Loading branch information
gitsimon authored Jul 20, 2023
1 parent 676100a commit 41fba27
Show file tree
Hide file tree
Showing 24 changed files with 310 additions and 186 deletions.
3 changes: 2 additions & 1 deletion pallets/acurast/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,9 @@ pub struct AcurastRegistrationExtra {
/// my extra registration parameters
}

pub type MaxAllowedSources = CU32<10>;

parameter_types! {
pub const MaxAllowedSources: u16 = 100;
pub const AcurastPalletId: PalletId = PalletId(*b"acrstpid");
}

Expand Down
21 changes: 8 additions & 13 deletions pallets/acurast/common/src/traits.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,9 @@
/// TODO: can be removed once we migrate to newer substrate version with XCMv3 and use [frame_support::traits::tokens::fungibles::Transfer] instead.
pub trait AssetTransfer {
type AssetId;
type Balance;
type AccountId;
type Error;
use frame_support::traits::Get;
use sp_std::fmt;
use sp_std::prelude::*;

fn transfer(
asset: Self::AssetId,
from: &Self::AccountId,
to: &Self::AccountId,
amount: Self::Balance,
) -> Result<(), Self::Error>;
}
/// A bound that can be used to restrict length sequence types such as [`frame_support::BoundedVec`] appearing in types used in dispatchable functions.
///
/// Similar to [`frame_support::Parameter`] without encoding traits, since bounds are never encoded.
pub trait ParameterBound: Get<u32> + Clone + Eq + fmt::Debug + scale_info::TypeInfo {}
impl<T> ParameterBound for T where T: Get<u32> + Clone + Eq + fmt::Debug + scale_info::TypeInfo {}
5 changes: 3 additions & 2 deletions pallets/acurast/common/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ pub(crate) const SCRIPT_LENGTH: u32 = 53;
/// Type representing the utf8 bytes of a string containing the value of an ipfs url.
/// The ipfs url is expected to point to a script.
pub type Script = BoundedVec<u8, ConstU32<SCRIPT_LENGTH>>;
pub type AllowedSources<AccountId, MaxAllowedSources> = BoundedVec<AccountId, MaxAllowedSources>;

pub fn is_valid_script(script: &Script) -> bool {
let script_len: u32 = script.len().try_into().unwrap_or(0);
Expand Down Expand Up @@ -71,11 +72,11 @@ pub type CertificateRevocationListUpdate = ListUpdate<SerialNumber>;

/// Structure representing a job registration.
#[derive(RuntimeDebug, Encode, Decode, TypeInfo, Clone, PartialEq)]
pub struct JobRegistration<AccountId, Extra> {
pub struct JobRegistration<AccountId, MaxAllowedSources: Get<u32>, Extra> {
/// The script to execute. It is a vector of bytes representing a utf8 string. The string needs to be a ipfs url that points to the script.
pub script: Script,
/// An optional array of the [AccountId]s allowed to fulfill the job. If the array is [None], then all sources are allowed.
pub allowed_sources: Option<Vec<AccountId>>,
pub allowed_sources: Option<AllowedSources<AccountId, MaxAllowedSources>>,
/// A boolean indicating if only verified sources can fulfill the job. A verified source is one that has provided a valid key attestation.
pub allow_only_verified_sources: bool,
/// The schedule describing the desired (multiple) execution(s) of the script.
Expand Down
27 changes: 15 additions & 12 deletions pallets/acurast/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,11 @@ pub use acurast_common::*;
pub use pallet::*;
pub use traits::*;

pub type JobRegistrationFor<T> =
JobRegistration<<T as frame_system::Config>::AccountId, <T as Config>::RegistrationExtra>;
pub type JobRegistrationFor<T> = JobRegistration<
<T as frame_system::Config>::AccountId,
<T as Config>::MaxAllowedSources,
<T as Config>::RegistrationExtra,
>;

#[frame_support::pallet]
pub mod pallet {
Expand All @@ -40,7 +43,7 @@ pub mod pallet {
type RegistrationExtra: Parameter + Member;
/// The max length of the allowed sources list for a registration.
#[pallet::constant]
type MaxAllowedSources: Get<u32>;
type MaxAllowedSources: Get<u32> + ParameterBound;
#[pallet::constant]
type MaxCertificateRevocationListUpdates: Get<u32>;
/// The ID for this pallet
Expand Down Expand Up @@ -352,8 +355,11 @@ pub mod pallet {
let registration = <StoredJobRegistration<T>>::get(&job_id.0, &job_id.1)
.ok_or(Error::<T>::JobRegistrationNotFound)?;

let mut current_allowed_sources =
registration.allowed_sources.clone().unwrap_or_default();
let mut current_allowed_sources = registration
.allowed_sources
.clone()
.unwrap_or_default()
.into_inner();
for update in &updates {
let position = current_allowed_sources
.iter()
Expand All @@ -368,16 +374,13 @@ pub mod pallet {
_ => {}
}
}
let max_allowed_sources_len = T::MaxAllowedSources::get() as usize;
let allowed_sources_len = current_allowed_sources.len();
ensure!(
allowed_sources_len <= max_allowed_sources_len,
Error::<T>::TooManyAllowedSources
);
let allowed_sources = if current_allowed_sources.is_empty() {
None
} else {
Some(current_allowed_sources)
Some(
AllowedSources::try_from(current_allowed_sources)
.map_err(|_| Error::<T>::TooManyAllowedSources)?,
)
};
<StoredJobRegistration<T>>::insert(
&job_id.0,
Expand Down
8 changes: 4 additions & 4 deletions pallets/acurast/src/migration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,16 @@ use sp_core::Get;
use super::*;

pub mod v1 {
use acurast_common::{Schedule, Script};
use acurast_common::{AllowedSources, Schedule, Script};
use frame_support::pallet_prelude::*;
use sp_std::prelude::*;

#[derive(RuntimeDebug, Encode, Decode, TypeInfo, Clone, PartialEq)]
pub struct JobRegistration<AccountId, Extra> {
pub struct JobRegistration<AccountId, MaxAllowedSources: Get<u32>, Extra> {
/// The script to execute. It is a vector of bytes representing a utf8 string. The string needs to be a ipfs url that points to the script.
pub script: Script,
/// An optional array of the [AccountId]s allowed to fulfill the job. If the array is [None], then all sources are allowed.
pub allowed_sources: Option<Vec<AccountId>>,
pub allowed_sources: Option<AllowedSources<AccountId, MaxAllowedSources>>,
/// A boolean indicating if only verified sources can fulfill the job. A verified source is one that has provided a valid key attestation.
pub allow_only_verified_sources: bool,
/// The schedule describing the desired (multiple) execution(s) of the script.
Expand Down Expand Up @@ -50,7 +50,7 @@ pub fn migrate<T: Config>() -> Weight {

fn migrate_to_v2<T: Config>() -> Weight {
StoredJobRegistration::<T>::translate::<
v1::JobRegistration<T::AccountId, T::RegistrationExtra>,
v1::JobRegistration<T::AccountId, T::MaxAllowedSources, T::RegistrationExtra>,
_,
>(|_k1, _k2, job| {
Some(JobRegistration {
Expand Down
14 changes: 8 additions & 6 deletions pallets/acurast/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use sp_io;
use sp_runtime::traits::{AccountIdConversion, AccountIdLookup, BlakeTwo256};
use sp_runtime::{generic, AccountId32};

use acurast_common::{JobModules, Schedule};
use acurast_common::{AllowedSources, JobModules, Schedule, CU32};

#[cfg(feature = "runtime-benchmarks")]
use crate::benchmarking::BenchmarkHelper;
Expand Down Expand Up @@ -150,10 +150,12 @@ impl pallet_balances::Config for Test {

impl parachain_info::Config for Test {}

pub type MaxAllowedSources = CU32<4>;

impl crate::Config for Test {
type RuntimeEvent = RuntimeEvent;
type RegistrationExtra = ();
type MaxAllowedSources = frame_support::traits::ConstU32<4>;
type MaxAllowedSources = MaxAllowedSources;
type MaxCertificateRevocationListUpdates = frame_support::traits::ConstU32<10>;
type PalletId = AcurastPalletId;
type RevocationListUpdateBarrier = Barrier;
Expand Down Expand Up @@ -213,9 +215,9 @@ pub fn invalid_script_2() -> Script {
}

pub fn job_registration(
allowed_sources: Option<Vec<AccountId>>,
allowed_sources: Option<AllowedSources<AccountId, MaxAllowedSources>>,
allow_only_verified_sources: bool,
) -> JobRegistration<AccountId, ()> {
) -> JobRegistration<AccountId, MaxAllowedSources, ()> {
JobRegistration {
script: script(),
allowed_sources,
Expand All @@ -235,7 +237,7 @@ pub fn job_registration(
}
}

pub fn invalid_job_registration_1() -> JobRegistration<AccountId, ()> {
pub fn invalid_job_registration_1() -> JobRegistration<AccountId, MaxAllowedSources, ()> {
JobRegistration {
script: invalid_script_1(),
allowed_sources: None,
Expand All @@ -255,7 +257,7 @@ pub fn invalid_job_registration_1() -> JobRegistration<AccountId, ()> {
}
}

pub fn invalid_job_registration_2() -> JobRegistration<AccountId, ()> {
pub fn invalid_job_registration_2() -> JobRegistration<AccountId, MaxAllowedSources, ()> {
JobRegistration {
script: invalid_script_2(),
allowed_sources: None,
Expand Down
31 changes: 8 additions & 23 deletions pallets/acurast/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::{
CertificateRevocationListUpdate, Error, ListUpdateOperation, SerialNumber,
};
use acurast_common::MultiOrigin;
use frame_support::{assert_err, assert_ok};
use frame_support::{assert_err, assert_ok, bounded_vec};
use hex_literal::hex;
use sp_runtime::AccountId32;

Expand Down Expand Up @@ -116,24 +116,7 @@ fn test_job_registration_failure_3() {
ExtBuilder::default().build().execute_with(|| {
let initial_job_id = Acurast::job_id_sequence();

let registration_1 = job_registration(
Some(vec![
alice_account_id(),
bob_account_id(),
charlie_account_id(),
dave_account_id(),
eve_account_id(),
]),
false,
);
let registration_2 = job_registration(Some(vec![]), false);
assert_err!(
Acurast::register(
RuntimeOrigin::signed(alice_account_id()).into(),
registration_1.clone()
),
Error::<Test>::TooManyAllowedSources
);
let registration = job_registration(Some(bounded_vec![]), false);

assert_eq!(
None,
Expand All @@ -146,7 +129,7 @@ fn test_job_registration_failure_3() {
assert_err!(
Acurast::register(
RuntimeOrigin::signed(alice_account_id()).into(),
registration_2.clone()
registration.clone()
),
Error::<Test>::TooFewAllowedSources
);
Expand All @@ -169,8 +152,10 @@ fn test_update_allowed_sources() {
let initial_job_id = Acurast::job_id_sequence();

let registration_1 = job_registration(None, false);
let registration_2 =
job_registration(Some(vec![alice_account_id(), bob_account_id()]), false);
let registration_2 = job_registration(
Some(bounded_vec![alice_account_id(), bob_account_id()]),
false,
);
let updates_1 = vec![
AllowedSourcesUpdate {
operation: ListUpdateOperation::Add,
Expand Down Expand Up @@ -249,7 +234,7 @@ fn test_update_allowed_sources() {
#[test]
fn test_update_allowed_sources_failure() {
let registration = job_registration(
Some(vec![
Some(bounded_vec![
alice_account_id(),
bob_account_id(),
charlie_account_id(),
Expand Down
25 changes: 21 additions & 4 deletions pallets/hyperdrive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ pub mod pallet {
},
};
use frame_system::pallet_prelude::*;
use pallet_acurast::ParameterBound;
use sp_arithmetic::traits::{CheckedRem, Zero};
use sp_runtime::traits::Hash;
use sp_std::collections::btree_set::BTreeSet;
Expand Down Expand Up @@ -98,7 +99,15 @@ pub mod pallet {
+ MaybeSerializeDeserialize
+ MaxEncodedLen
+ TypeInfo;
type RegistrationExtra: From<RegistrationExtra<Self::Balance, Self::AccountId>>;
type RegistrationExtra: From<
RegistrationExtra<Self::Balance, Self::AccountId, Self::MaxSlots>,
>;
/// The max length of the allowed sources list for a registration.
#[pallet::constant]
type MaxAllowedSources: Get<u32> + ParameterBound;
/// The maximum allowed slots and therefore maximum length of the planned executions per job.
#[pallet::constant]
type MaxSlots: Get<u32> + ParameterBound;

/// The hashing system (algorithm) being used in the runtime (e.g. Blake2).
type TargetChainHashing: Hash<Output = Self::TargetChainHash> + TypeInfo;
Expand All @@ -108,9 +117,17 @@ pub mod pallet {
///
/// **NOTE**: the quorum size must be larger than `ceil(number of transmitters / 2)`, otherwise multiple root hashes could become valid in terms of [`Pallet::validate_state_merkle_root`].
type TransmissionQuorum: Get<u8>;
type MessageParser: MessageParser<Self::AccountId, Self::RegistrationExtra>;

type ActionExecutor: ActionExecutor<Self::AccountId, Self::RegistrationExtra>;
type MessageParser: MessageParser<
Self::AccountId,
Self::MaxAllowedSources,
Self::RegistrationExtra,
>;

type ActionExecutor: ActionExecutor<
Self::AccountId,
Self::MaxAllowedSources,
Self::RegistrationExtra,
>;

type WeightInfo: WeightInfo;
}
Expand Down
12 changes: 9 additions & 3 deletions pallets/hyperdrive/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use frame_support::{
};
use frame_system as system;
use hex_literal::hex;
use pallet_acurast::CU32;
use sp_core::H256;
use sp_core::*;
use sp_runtime::traits::Keccak256;
Expand Down Expand Up @@ -84,6 +85,8 @@ impl system::Config for Test {
type MaxConsumers = frame_support::traits::ConstU32<16>;
}

pub type MaxAllowedSources = CU32<4>;

impl crate::Config for Test {
type RuntimeEvent = RuntimeEvent;
type ParsableAccountId = AcurastAccountId;
Expand All @@ -92,14 +95,17 @@ impl crate::Config for Test {
type TargetChainBlockNumber = u64;
type Balance = Balance;
type RegistrationExtra =
RegistrationExtra<Self::Balance, <Self as frame_system::Config>::AccountId>;
RegistrationExtra<Self::Balance, <Self as frame_system::Config>::AccountId, Self::MaxSlots>;
type MaxAllowedSources = MaxAllowedSources;
type MaxSlots = CU32<64>;
type TargetChainHashing = Keccak256;
type TransmissionRate = TransmissionRate;
type TransmissionQuorum = TransmissionQuorum;
type MessageParser = TezosParser<
Self::Balance,
AcurastAccountId,
<Self as frame_system::Config>::AccountId,
Self::MaxSlots,
Self::RegistrationExtra,
>;
type ActionExecutor = ();
Expand Down Expand Up @@ -132,8 +138,8 @@ pub fn events() -> Vec<RuntimeEvent> {

pub type Balance = u128;

impl<AccountId, Extra> ActionExecutor<AccountId, Extra> for () {
fn execute(_: ParsedAction<AccountId, Extra>) -> DispatchResultWithPostInfo {
impl<AccountId, Extra> ActionExecutor<AccountId, MaxAllowedSources, Extra> for () {
fn execute(_: ParsedAction<AccountId, MaxAllowedSources, Extra>) -> DispatchResultWithPostInfo {
Ok(().into())
}
}
Loading

0 comments on commit 41fba27

Please sign in to comment.