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 Sep 26, 2024
1 parent 3eb7784 commit 14e1bb0
Show file tree
Hide file tree
Showing 4 changed files with 194 additions and 51 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 {
FullRights, // all balances, assets and llm transfers, + batch + llm.remark
PooledMeritsRightsOnly, // llm.send_llm_to_politipool only, + batch + llm.remark
}

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

impl MinistryOfFinanceCallFilter {
fn tier_filter(&self, c: &RuntimeCall) -> bool {
match self {
Self::FullRights => 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::PooledMeritsRightsOnly => 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::FullRights, _) => true,
(_, MinistryOfFinanceCallFilter::PooledMeritsRightsOnly) => false,
_ => false,
}
}
}

#[derive(
Clone,
Eq,
Expand Down Expand Up @@ -953,6 +1014,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::FullRights.filter(&call));
assert!(MinistryOfFinanceCallFilter::PooledMeritsRightsOnly.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::FullRights.filter(&call));
assert!(MinistryOfFinanceCallFilter::PooledMeritsRightsOnly.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::FullRights.filter(&call));
assert!(MinistryOfFinanceCallFilter::PooledMeritsRightsOnly.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::FullRights.filter(&call));
assert!(MinistryOfFinanceCallFilter::PooledMeritsRightsOnly.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::FullRights.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::FullRights.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::FullRights.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::PooledMeritsRightsOnly.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::PooledMeritsRightsOnly.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::PooledMeritsRightsOnly.filter(&call));
});
}
}

#[cfg(test)]
mod multiplier_tests {
use frame_support::{
Expand Down
18 changes: 16 additions & 2 deletions 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, ContractsCallFilter, SenateAccountCallFilter,
MinistryOfFinanceCallFilter,
};

/// Constant values used within the runtime.
Expand Down Expand Up @@ -1476,13 +1477,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 @@ -1534,6 +1537,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 @@ -1794,6 +1807,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 @@ -1853,8 +1867,8 @@ pub type Executive = frame_executive::Executive<
// All migrations executed on runtime upgrade as a nested tuple of types implementing
// `OnRuntimeUpgrade`.
type Migrations = (
// Migrations for spec version 26 - delete when bumping to v27
crate::migrations::add_onchain_identities::Migration<Runtime>,
// Migrations for spec version 27 - delete when bumping to v28
crate::migrations::add_ministry_of_finance_office_pallet::Migration<Runtime>,
);

type EventRecord = frame_system::EventRecord<
Expand Down
58 changes: 10 additions & 48 deletions substrate/bin/node/runtime/src/migrations.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use super::*;
use frame_support::traits::OnRuntimeUpgrade;
use frame_support::{pallet_prelude::*, traits::OnRuntimeUpgrade};

#[cfg(feature = "try-runtime")]
use sp_std::vec::Vec;
Expand All @@ -9,11 +9,8 @@ use sp_runtime::TryRuntimeError;

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

pub mod add_onchain_identities {
pub mod add_ministry_of_finance_office_pallet {
use super::*;
use crate::Identity;
use pallet_identity::{Data, IdentityInfo, Judgement};
use sp_core::crypto::Ss58Codec;

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

Expand All @@ -24,54 +21,19 @@ pub mod add_onchain_identities {
}

fn on_runtime_upgrade() -> Weight {
let identities = vec![
("5EYCAe5hvejUE1BUTDSnxDfCqVkADRicSKqbcJrduV1KCDmk", b"Vault".to_vec()),
("5EYCAe5hveooUENA5d7dwq3caqM4LLBzktNumMKmhNRXu4JE", b"Senate".to_vec()),
(
"5EYCAe5iXF2YZuVZv1vig4xvf1CcDVocZCWYrv3TVSXpMTYA",
b"Citizenship Office".to_vec(),
),
//("5EYCAe5ijiYfyeZ2JJCGq56LmPyNRAKzpG4QkoQkkQNB5e6Z", b"Treasury"), - skipping this as Polkadot.js Apps have it builtin
("5EYCAe5g8CDuMsTief7QBxfvzDFEfws6ueXTUhsbx5V81nGH", b"Congress".to_vec()),
("5GmkwXZ94cuLMMbtE5VtBaLpFDehoEpy6MZnJhkCSicxePs2", b"SORA Bridge".to_vec()),
("5DSfG3S7qSZzrDMj3F3qYybXAy1BLsVpRG5CNwRdwwNPjgVm", b"MEXC".to_vec()),
("5HEX1wk33NHAeEJV3B6goDHMJTqhy411znCUmfEAxKkQeqds", b"Coinstore".to_vec()),
("5EYCAe5iXF2YZiuxDWAcwtPMDaG7ihsYzPxajcNKRpNyD1Zi", b"Company Registry Office".to_vec()),
("5EYCAe5iXF2YZzoQHqGhj9dtcsUNB4puM5GqR1BwVHZyaWxM", b"Land Registry Office".to_vec()),
("5EYCAe5iXF2Ya2c2iKjeFWUAXAEcMyoKCBPvhRy8YprHTLNd", b"Metaverse Land Registry Office".to_vec()),
("5EYCAe5iXF2YZfPZ4arKGSYZvQruDacGHkuw4qAsQSQsKpMK", b"Asset Registry Office".to_vec()),
("5EYCAe5iXF2YZpCZr7ALYUUYaNpMXde3NUXxYn1Sc1YRM4gV", b"Ministry of Finance Office".to_vec()),
("5FBQRNJfzsttYvw1XnSwxwSUmb7A3EYm4q8aiscADREqvzYz", b"Wrapped LLD Token Contract".to_vec()),
("5EYCAe5ijGqt3WEM9aKUBdth51NEBNz9P84NaUMWZazzWt7c", b"LLM Politipool Technical Account".to_vec()),
("5GsBCWqN6mnrq4arSMBuT4uQ8GJKwgeBsa5UyCvTN6DyVj3S", b"Emirex".to_vec()),
("5FhqVhuxGtcUBYXhyjtyvjh9jLucmoWzejcomA4HcqW9tBbP", b"LLM/LLD DEX Pool".to_vec()),
];
let mut weight = DbWeight::get().reads(0);
for (addr, display) in identities {
let account = AccountId::from_ss58check(addr).unwrap();
let id = IdentityInfo {
twitter: Data::None,
additional: vec![].try_into().unwrap(),
display: Data::Raw(display.try_into().unwrap()),
legal: Data::None,
web: Data::None,
riot: Data::None,
email: Data::None,
pgp_fingerprint: None,
image: Data::None,
};
let judgements = vec![(0, Judgement::KnownGood)].try_into().unwrap();
let set_identity_weight =
Identity::set_identity_no_deposit(&account, judgements, id);
weight = weight.saturating_add(set_identity_weight);
}
let mut weight = DbWeight::get().reads(1);

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

weight
}

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

0 comments on commit 14e1bb0

Please sign in to comment.