Skip to content

Commit

Permalink
Ab/make parentchain pallet instantiable (#241)
Browse files Browse the repository at this point in the history
* make_parentchain_pallet_instantiable

* init_shard_vault

* more testing

* unit test account mirror

* introduce parentchain genesis storage with write-once lock
  • Loading branch information
brenzi committed Dec 28, 2023
1 parent 8469a05 commit 91321c8
Show file tree
Hide file tree
Showing 5 changed files with 261 additions and 34 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 4 additions & 3 deletions parentchain/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "pallet-parentchain"
description = "The remote attestation registry and verification pallet for integritee blockchains and parachains"
version = "0.9.0"
version = "0.10.0"
authors = ["Integritee AG <hello@integritee.network>"]
homepage = "https://integritee.network/"
repository = "https://github.com/integritee-network/pallets/"
Expand All @@ -16,7 +16,8 @@ serde = { version = "1.0.13", features = ["derive"], optional = true }

# substrate dependencies
frame-support = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" }
frame-system = { default-features = false, package = "frame-system", git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" }
frame-system = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" }
pallet-balances = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" }
sp-core = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" }
sp-io = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" }
sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" }
Expand All @@ -25,7 +26,6 @@ sp-std = { default-features = false, git = "https://github.com/paritytech/substr
[dev-dependencies]
env_logger = "0.9.0"
sp-keyring = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" }
pallet-balances = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" }

[features]
default = ["std"]
Expand All @@ -37,6 +37,7 @@ std = [
# substrate dependencies
"frame-support/std",
"frame-system/std",
"pallet-balances/std",
"sp-core/std",
"sp-io/std",
"sp-runtime/std",
Expand Down
128 changes: 112 additions & 16 deletions parentchain/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,63 +2,159 @@

pub use pallet::*;

/// Index/Nonce type for parentchain runtime
type ParentchainIndex = u32;
/// Balance type for parentchain runtime
type ParentchainBalance = u128;
/// AccountData type for parentchain runtime
type ParentchainAccountData = pallet_balances::AccountData<ParentchainBalance>;

#[frame_support::pallet]
pub mod pallet {
use crate::weights::WeightInfo;
use crate::{weights::WeightInfo, ParentchainAccountData, ParentchainIndex};
use frame_support::{pallet_prelude::*, sp_runtime::traits::Header};
use frame_system::pallet_prelude::*;
use frame_system::{pallet_prelude::*, AccountInfo};

const STORAGE_VERSION: StorageVersion = StorageVersion::new(1);
#[pallet::pallet]
pub struct Pallet<T>(_);
#[pallet::storage_version(STORAGE_VERSION)]
#[pallet::without_storage_info]
pub struct Pallet<T, I = ()>(PhantomData<(T, I)>);

/// Configuration trait.
#[pallet::config]
pub trait Config: frame_system::Config {
type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
pub trait Config<I: 'static = ()>: frame_system::Config {
type RuntimeEvent: From<Event<Self, I>>
+ IsType<<Self as frame_system::Config>::RuntimeEvent>;
type WeightInfo: WeightInfo;
}

#[pallet::event]
#[pallet::generate_deposit(pub(super) fn deposit_event)]
pub enum Event<T: Config> {
pub enum Event<T: Config<I>, I: 'static = ()> {
/// a parentchain block has been registered
SetBlock { block_number: T::BlockNumber, parent_hash: T::Hash, block_hash: T::Hash },
SetBlock {
block_number: T::BlockNumber,
parent_hash: T::Hash,
block_hash: T::Hash,
},
ShardVaultInitialized {
account: T::AccountId,
},
AccountInfoForcedFor {
account: T::AccountId,
},
ParentchainGeneisInitialized {
hash: T::Hash,
},
}

#[pallet::error]
pub enum Error<T, I = ()> {
/// Sahrd vault has been previously initialized and can't be overwritten
ShardVaultAlreadyInitialized,
/// Parentchain genesis hash has already been initialized and can^t be overwritten
GenesisAlreadyInitialized,
}

/// The parentchain mirror of full account information for a particular account ID.
#[pallet::storage]
#[pallet::getter(fn account)]
pub type Account<T: Config<I>, I: 'static = ()> = StorageMap<
_,
Blake2_128Concat,
T::AccountId,
AccountInfo<ParentchainIndex, ParentchainAccountData>,
ValueQuery,
>;

/// The current block number being processed. Set by `set_block`.
#[pallet::storage]
#[pallet::getter(fn shard_vault)]
pub(super) type ShardVault<T: Config<I>, I: 'static = ()> =
StorageValue<_, T::AccountId, OptionQuery>;

#[pallet::storage]
#[pallet::getter(fn parentchain_genesis_hash)]
pub(super) type ParentchainGenesisHash<T: Config<I>, I: 'static = ()> =
StorageValue<_, T::Hash, OptionQuery>;

/// The current block number being processed. Set by `set_block`.
#[pallet::storage]
#[pallet::getter(fn block_number)]
pub(super) type Number<T: Config> = StorageValue<_, T::BlockNumber, ValueQuery>;
pub(super) type Number<T: Config<I>, I: 'static = ()> =
StorageValue<_, T::BlockNumber, OptionQuery>;

/// Hash of the previous block. Set by `set_block`.
#[pallet::storage]
#[pallet::getter(fn parent_hash)]
pub(super) type ParentHash<T: Config> = StorageValue<_, T::Hash, ValueQuery>;
pub(super) type ParentHash<T: Config<I>, I: 'static = ()> =
StorageValue<_, T::Hash, OptionQuery>;

/// Hash of the last block. Set by `set_block`.
#[pallet::storage]
#[pallet::getter(fn block_hash)]
pub(super) type BlockHash<T: Config> = StorageValue<_, T::Hash, ValueQuery>;
pub(super) type BlockHash<T: Config<I>, I: 'static = ()> =
StorageValue<_, T::Hash, OptionQuery>;

#[pallet::hooks]
impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {}
impl<T: Config<I>, I: 'static> Hooks<BlockNumberFor<T>> for Pallet<T, I> {}

#[pallet::call]
impl<T: Config> Pallet<T> {
impl<T: Config<I>, I: 'static> Pallet<T, I> {
#[pallet::call_index(0)]
#[pallet::weight(<T as Config>::WeightInfo::set_block())]
#[pallet::weight(T::WeightInfo::set_block())]
pub fn set_block(origin: OriginFor<T>, header: T::Header) -> DispatchResult {
ensure_root(origin)?;
<Number<T>>::put(header.number());
<ParentHash<T>>::put(header.parent_hash());
<BlockHash<T>>::put(header.hash());
<Number<T, I>>::put(header.number());
<ParentHash<T, I>>::put(header.parent_hash());
<BlockHash<T, I>>::put(header.hash());
Self::deposit_event(Event::SetBlock {
block_number: *header.number(),
parent_hash: *header.parent_hash(),
block_hash: header.hash(),
});
Ok(())
}

#[pallet::call_index(1)]
#[pallet::weight(T::WeightInfo::set_block())]
pub fn init_shard_vault(origin: OriginFor<T>, account: T::AccountId) -> DispatchResult {
ensure_root(origin)?;
ensure!(Self::shard_vault().is_none(), Error::<T, I>::ShardVaultAlreadyInitialized);
<ShardVault<T, I>>::put(account.clone());
Self::deposit_event(Event::ShardVaultInitialized { account });
Ok(())
}

#[pallet::call_index(2)]
#[pallet::weight(T::WeightInfo::set_block())]
pub fn init_parentchain_genesis_hash(
origin: OriginFor<T>,
genesis: T::Hash,
) -> DispatchResult {
ensure_root(origin)?;
ensure!(
Self::parentchain_genesis_hash().is_none(),
Error::<T, I>::GenesisAlreadyInitialized
);
<ParentchainGenesisHash<T, I>>::put(genesis);
Self::deposit_event(Event::ParentchainGeneisInitialized { hash: genesis });
Ok(())
}

#[pallet::call_index(3)]
#[pallet::weight(T::WeightInfo::set_block())]
pub fn force_account_info(
origin: OriginFor<T>,
account: T::AccountId,
account_info: AccountInfo<ParentchainIndex, ParentchainAccountData>,
) -> DispatchResult {
ensure_root(origin)?;
<crate::pallet::Account<T, I>>::insert(&account, account_info);
Self::deposit_event(crate::pallet::Event::AccountInfoForcedFor { account });
Ok(())
}
}
}

Expand Down
16 changes: 12 additions & 4 deletions parentchain/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,21 @@ frame_support::construct_runtime!(
NodeBlock = Block,
UncheckedExtrinsic = UncheckedExtrinsic,
{
System: frame_system::{Pallet, Call, Config, Storage, Event<T>},
Balances: pallet_balances::{Pallet, Call, Storage, Config<T>, Event<T>},
Parentchain: pallet_parentchain::{Pallet, Call, Storage, Event<T>},
System: frame_system::{Pallet, Call, Config, Event<T>},
Balances: pallet_balances::{Pallet, Call, Config<T>, Event<T>},
ParentchainIntegritee: pallet_parentchain::<Instance1>::{Pallet, Call, Event<T>},
ParentchainTargetA: pallet_parentchain::<Instance2>::{Pallet, Call, Event<T>},
}
);

impl Config for Test {
pub type ParentchainInstanceIntegritee = pallet_parentchain::Instance1;
impl Config<ParentchainInstanceIntegritee> for Test {
type RuntimeEvent = RuntimeEvent;
type WeightInfo = ();
}

pub type ParentchainInstanceTargetA = pallet_parentchain::Instance2;
impl Config<crate::mock::ParentchainInstanceTargetA> for Test {
type RuntimeEvent = RuntimeEvent;
type WeightInfo = ();
}
Expand Down
Loading

0 comments on commit 91321c8

Please sign in to comment.