Skip to content

Commit

Permalink
BLOCKCHAIN-481 - add Ministry of Finance office
Browse files Browse the repository at this point in the history
  • Loading branch information
kacperzuk-neti committed Jul 23, 2024
1 parent 761fdf5 commit 7436530
Show file tree
Hide file tree
Showing 4 changed files with 187 additions and 73 deletions.
6 changes: 5 additions & 1 deletion substrate/bin/node/cli/src/chain_spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ use kitchensink_runtime::{
IdentityOfficePalletId, AssetRegistryOfficeConfig,
LandRegistryOfficePalletId, AssetRegistryOfficePalletId,
MetaverseLandRegistryOfficeConfig, MetaverseLandRegistryOfficePalletId,
SenateConfig,
SenateConfig, MinistryOfFinanceOfficeConfig,
impls::{RegistryCallFilter, IdentityCallFilter, NftsCallFilter},
};
use pallet_im_online::sr25519::AuthorityId as ImOnlineId;
Expand Down Expand Up @@ -455,6 +455,10 @@ pub fn testnet_genesis(
admin: offices_admin.clone(),
clerks: nfts_clerks.clone(),
},
ministry_of_finance_office: MinistryOfFinanceOfficeConfig {
admin: offices_admin.clone(),
clerks: vec![],
},
asset_registry_office: AssetRegistryOfficeConfig {
admin: offices_admin,
clerks: nfts_clerks,
Expand Down
163 changes: 163 additions & 0 deletions substrate/bin/node/runtime/src/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,67 @@ impl InstanceFilter<RuntimeCall> for RegistryCallFilter {
}
}

#[derive(
Clone,
Eq,
PartialEq,
Encode,
Decode,
RuntimeDebug,
MaxEncodedLen,
scale_info::TypeInfo,
Serialize,
Deserialize,
)]
pub enum MinistryOfFinanceCallFilter {
Tier1, // all balances, assets and llm transfers, + batch + llm.remark
Tier2, // llm.send_llm_to_politipool only, + batch + llm.remark
}

impl Default for MinistryOfFinanceCallFilter {
fn default() -> Self {
MinistryOfFinanceCallFilter::Tier2
}
}

impl MinistryOfFinanceCallFilter {
fn tier_filter(&self, c: &RuntimeCall) -> bool {
match self {
Self::Tier1 => matches!(c,
RuntimeCall::LLM(pallet_llm::Call::send_llm { .. }) |
RuntimeCall::LLM(pallet_llm::Call::send_llm_to_politipool { .. }) |
RuntimeCall::Assets(pallet_assets::Call::transfer { .. }) |
RuntimeCall::Assets(pallet_assets::Call::transfer_keep_alive { .. }) |
RuntimeCall::Balances(pallet_balances::Call::transfer { .. }) |
RuntimeCall::Balances(pallet_balances::Call::transfer_keep_alive { .. })
),
Self::Tier2 => matches!(c,
RuntimeCall::LLM(pallet_llm::Call::send_llm_to_politipool { .. })
),
}
}
}

impl InstanceFilter<RuntimeCall> for MinistryOfFinanceCallFilter {
fn filter(&self, c: &RuntimeCall) -> bool {
match c {
RuntimeCall::Utility(pallet_utility::Call::batch { calls }) => calls.iter().all(|call| self.filter(call)),
RuntimeCall::Utility(pallet_utility::Call::batch_all { calls }) => calls.iter().all(|call| self.filter(call)),
RuntimeCall::LLM(pallet_llm::Call::remark { .. }) => true,
_ => self.tier_filter(c),
}
}

fn is_superset(&self, o: &Self) -> bool {
match (self, o) {
(x, y) if x == y => true,
(MinistryOfFinanceCallFilter::Tier1, _) => true,
(_, MinistryOfFinanceCallFilter::Tier2) => false,
_ => false,
}
}
}

#[derive(
Clone,
Eq,
Expand Down Expand Up @@ -942,6 +1003,108 @@ mod council_filter_tests {
}
}

#[cfg(test)]
mod ministry_of_finance_call_filter_tests {
use super::{MinistryOfFinanceCallFilter, RuntimeCall};
use frame_support::{PalletId, traits::InstanceFilter};
use sp_runtime::{traits::AccountIdConversion, AccountId32};


fn accid() -> AccountId32 {
PalletId(*b"12345678").into_account_truncating()
}

fn acc() -> sp_runtime::MultiAddress<AccountId32, ()> {
accid().into()
}

#[test]
fn allows_remark() {
sp_io::TestExternalities::default().execute_with(|| {
let call = RuntimeCall::LLM(pallet_llm::Call::remark { data: vec![].try_into().unwrap() });
assert!(MinistryOfFinanceCallFilter::Tier1.filter(&call));
assert!(MinistryOfFinanceCallFilter::Tier2.filter(&call));
});
}

#[test]
fn allows_batch() {
sp_io::TestExternalities::default().execute_with(|| {
let call = RuntimeCall::LLM(pallet_llm::Call::remark { data: vec![].try_into().unwrap() });
let call = RuntimeCall::Utility(pallet_utility::Call::batch { calls: vec![call] }).into();
assert!(MinistryOfFinanceCallFilter::Tier1.filter(&call));
assert!(MinistryOfFinanceCallFilter::Tier2.filter(&call));
});
}

#[test]
fn allows_batch_all() {
sp_io::TestExternalities::default().execute_with(|| {
let call = RuntimeCall::LLM(pallet_llm::Call::remark { data: vec![].try_into().unwrap() });
let call = RuntimeCall::Utility(pallet_utility::Call::batch_all { calls: vec![call] }).into();
assert!(MinistryOfFinanceCallFilter::Tier1.filter(&call));
assert!(MinistryOfFinanceCallFilter::Tier2.filter(&call));
});
}

#[test]
fn allows_send_to_politipool() {
sp_io::TestExternalities::default().execute_with(|| {
let call = RuntimeCall::LLM(pallet_llm::Call::send_llm_to_politipool { to_account: accid(), amount: 1u8.into() });
assert!(MinistryOfFinanceCallFilter::Tier1.filter(&call));
assert!(MinistryOfFinanceCallFilter::Tier2.filter(&call));
});
}

#[test]
fn allows_tier1_liquid_transfer_lld() {
sp_io::TestExternalities::default().execute_with(|| {
let call = RuntimeCall::Balances(pallet_balances::Call::transfer { dest: acc(), value: 1u8.into() });
assert!(MinistryOfFinanceCallFilter::Tier1.filter(&call));
});
}

#[test]
fn allows_tier1_liquid_transfer_llm() {
sp_io::TestExternalities::default().execute_with(|| {
let call = RuntimeCall::LLM(pallet_llm::Call::send_llm { to_account: accid(), amount: 1u8.into() });
assert!(MinistryOfFinanceCallFilter::Tier1.filter(&call));
});
}

#[test]
fn allows_tier1_liquid_transfer_assets() {
sp_io::TestExternalities::default().execute_with(|| {
let call = RuntimeCall::Assets(pallet_assets::Call::transfer { id: 1u32.into(), target: acc(), amount: 1u8.into() });
assert!(MinistryOfFinanceCallFilter::Tier1.filter(&call));
});
}

#[test]
fn disallows_tier2_liquid_transfer_lld() {
sp_io::TestExternalities::default().execute_with(|| {
let call = RuntimeCall::Balances(pallet_balances::Call::transfer { dest: acc(), value: 1u8.into() });
assert!(!MinistryOfFinanceCallFilter::Tier2.filter(&call));
});
}

#[test]
fn disallows_tier2_liquid_transfer_llm() {
sp_io::TestExternalities::default().execute_with(|| {
let call = RuntimeCall::LLM(pallet_llm::Call::send_llm { to_account: accid(), amount: 1u8.into() });
assert!(!MinistryOfFinanceCallFilter::Tier2.filter(&call));
});
}

#[test]
fn disallows_tier2_liquid_transfer_assets() {
sp_io::TestExternalities::default().execute_with(|| {
let call = RuntimeCall::Assets(pallet_assets::Call::transfer { id: 1u32.into(), target: acc(), amount: 1u8.into() });
assert!(!MinistryOfFinanceCallFilter::Tier2.filter(&call));
});
}
}

#[cfg(test)]
mod multiplier_tests {
use frame_support::{
Expand Down
17 changes: 16 additions & 1 deletion substrate/bin/node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ use impls::{
Author, ToAccountId,
IdentityCallFilter, RegistryCallFilter, NftsCallFilter, OnLLMPoliticsUnlock,
ContainsMember, CouncilAccountCallFilter, EnsureCmp, SenateAccountCallFilter,
MinistryOfFinanceCallFilter,
};

/// Constant values used within the runtime.
Expand Down Expand Up @@ -1481,13 +1482,15 @@ parameter_types! {
pub const LandRegistryOfficePalletId: PalletId = PalletId(*b"off/land");
pub const MetaverseLandRegistryOfficePalletId: PalletId = PalletId(*b"off/meta");
pub const AssetRegistryOfficePalletId: PalletId = PalletId(*b"off/asse");
pub const MinistryOfFinanceOfficePalletId: PalletId = PalletId(*b"off/fina");
}

type IdentityOfficeInstance = pallet_office::Instance1;
type CompanyRegistryOfficeInstance = pallet_office::Instance2;
type LandRegistryOfficeInstance = pallet_office::Instance3;
type MetaverseLandRegistryOfficeInstance = pallet_office::Instance4;
type AssetRegistryOfficeInstance = pallet_office::Instance5;
type MinistryOfFinanceOfficeInstance = pallet_office::Instance6;

impl pallet_office::Config<IdentityOfficeInstance> for Runtime {
type RuntimeCall = RuntimeCall;
Expand Down Expand Up @@ -1539,6 +1542,16 @@ impl pallet_office::Config<AssetRegistryOfficeInstance> for Runtime {
type WeightInfo = ();
}

impl pallet_office::Config<MinistryOfFinanceOfficeInstance> for Runtime {
type RuntimeCall = RuntimeCall;
type RuntimeEvent = RuntimeEvent;
type PalletId = MinistryOfFinanceOfficePalletId;
type ForceOrigin = EnsureRoot<AccountId>;
type AdminOrigin = EnsureSigned<AccountId>;
type CallFilter = MinistryOfFinanceCallFilter;
type WeightInfo = ();
}

parameter_types! {
pub const LLDBridgePalletId: PalletId = PalletId(*b"lldbridg");
pub const LLMBridgePalletId: PalletId = PalletId(*b"llmbridg");
Expand Down Expand Up @@ -1799,6 +1812,7 @@ construct_runtime!(
AssetConversionTxPayment: pallet_asset_conversion_tx_payment = 64,
ContractsRegistry: pallet_contracts_registry = 65,
SenateAccount: pallet_custom_account::<Instance2> = 66,
MinistryOfFinanceOffice: pallet_office::<Instance6> = 67,

// Sora Bridge:
LeafProvider: leaf_provider = 80,
Expand Down Expand Up @@ -1920,7 +1934,8 @@ mod staking_v12 {
// All migrations executed on runtime upgrade as a nested tuple of types implementing
// `OnRuntimeUpgrade`.
type Migrations = (
crate::migrations::add_senate_account_pallet::Migration<Runtime>,
// Migrations for spec version 26 - delete when bumping to v27
crate::migrations::add_ministry_of_finance_office_pallet::Migration<Runtime>,
);

type EventRecord = frame_system::EventRecord<
Expand Down
74 changes: 3 additions & 71 deletions substrate/bin/node/runtime/src/migrations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use sp_runtime::TryRuntimeError;

type DbWeight = <Runtime as frame_system::Config>::DbWeight;

pub mod add_contracts_registry_pallet {
pub mod add_ministry_of_finance_office_pallet {
use super::*;

pub struct Migration<T>(sp_std::marker::PhantomData<T>);
Expand All @@ -23,76 +23,8 @@ pub mod add_contracts_registry_pallet {
fn on_runtime_upgrade() -> Weight {
let mut weight = DbWeight::get().reads(1);

if StorageVersion::get::<ContractsRegistry>() == 0 {
StorageVersion::new(1).put::<ContractsRegistry>();
weight = weight.saturating_add(DbWeight::get().reads_writes(1, 1));
}

weight
}

#[cfg(feature = "try-runtime")]
fn post_upgrade(_state: Vec<u8>) -> Result<(), TryRuntimeError> {
Ok(())
}
}
}

pub mod add_sora_bridge {
use super::*;

pub struct Migration<T>(sp_std::marker::PhantomData<T>);

impl OnRuntimeUpgrade for Migration<Runtime> {
#[cfg(feature = "try-runtime")]
fn pre_upgrade() -> Result<Vec<u8>, TryRuntimeError> {
Ok(().encode())
}

fn on_runtime_upgrade() -> Weight {
let mut weight = DbWeight::get().reads(1);

if StorageVersion::get::<SubstrateBridgeInboundChannel>() == 0 {
StorageVersion::new(1).put::<SubstrateBridgeInboundChannel>();
weight = weight.saturating_add(DbWeight::get().reads_writes(1, 1));
}

if StorageVersion::get::<SubstrateBridgeOutboundChannel>() == 0 {
StorageVersion::new(1).put::<SubstrateBridgeOutboundChannel>();
weight = weight.saturating_add(DbWeight::get().reads_writes(1, 1));
}

if StorageVersion::get::<SubstrateDispatch>() == 0 {
StorageVersion::new(1).put::<SubstrateDispatch>();
weight = weight.saturating_add(DbWeight::get().reads_writes(1, 1));
}

weight
}

#[cfg(feature = "try-runtime")]
fn post_upgrade(_state: Vec<u8>) -> Result<(), TryRuntimeError> {
Ok(())
}
}
}

pub mod add_senate_account_pallet {
use super::*;

pub struct Migration<T>(sp_std::marker::PhantomData<T>);

impl OnRuntimeUpgrade for Migration<Runtime> {
#[cfg(feature = "try-runtime")]
fn pre_upgrade() -> Result<Vec<u8>, TryRuntimeError> {
Ok(().encode())
}

fn on_runtime_upgrade() -> Weight {
let mut weight = DbWeight::get().reads(1);

if StorageVersion::get::<SenateAccount>() == 0 {
StorageVersion::new(1).put::<SenateAccount>();
if StorageVersion::get::<MinistryOfFinanceOffice>() == 0 {
StorageVersion::new(1).put::<MinistryOfFinanceOffice>();
weight = weight.saturating_add(DbWeight::get().reads_writes(1, 1));
}

Expand Down

0 comments on commit 7436530

Please sign in to comment.