Skip to content

Commit

Permalink
Add history seeding pallet
Browse files Browse the repository at this point in the history
  • Loading branch information
dariolina authored and dastansam committed Sep 5, 2024
1 parent f73c757 commit 8a18594
Show file tree
Hide file tree
Showing 9 changed files with 286 additions and 5 deletions.
16 changes: 16 additions & 0 deletions Cargo.lock

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

38 changes: 38 additions & 0 deletions crates/pallet-history-seeding/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
[package]
name = "pallet-history-seeding"
version = "0.1.0"
edition = "2021"
description = "A pallet for seeding history of the network"
authors = ["Dariia Porechna <[email protected]>"]
repository = "https://github.com/autonomys/subspace"
license = "Apache-2.0"
readme = "README.md"
include = [
"/src",
"/Cargo.toml",
"/README.md",
]

[dependencies]
codec = { package = "parity-scale-codec", version = "3.6.12", default-features = false, features = ["derive"] }
scale-info = { version = "2.11.2", default-features = false, features = ["derive"] }
frame-support = { default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "5626154d0781ac9a6ffd5a6207ed237f425ae631" }
frame-system = { default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "5626154d0781ac9a6ffd5a6207ed237f425ae631" }
sp-std = { default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "5626154d0781ac9a6ffd5a6207ed237f425ae631" }

[dev-dependencies]
pallet-sudo = { default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "5626154d0781ac9a6ffd5a6207ed237f425ae631", features = ["std"] }
sp-core = { default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "5626154d0781ac9a6ffd5a6207ed237f425ae631" }
sp-io = { default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "5626154d0781ac9a6ffd5a6207ed237f425ae631" }
sp-runtime = { default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "5626154d0781ac9a6ffd5a6207ed237f425ae631" }

[features]
default = ["std"]
std = [
"codec/std",
"scale-info/std",
"frame-support/std",
"frame-system/std",
"sp-std/std",
]
try-runtime = ["frame-support/try-runtime"]
5 changes: 5 additions & 0 deletions crates/pallet-history-seeding/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Pallet History Seeding

The history seeding pallet allows an authorized account to add remarks to the blockchain, which can be used to seed historical data or important information into the chain's history. The authorized account for seeding can be set by root.

License: Apache-2.0
100 changes: 100 additions & 0 deletions crates/pallet-history-seeding/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
#![cfg_attr(not(feature = "std"), no_std)]

use frame_support::pallet_prelude::*;
use frame_support::traits::{BuildGenesisConfig, Get};

#[cfg(test)]
mod tests;

pub use pallet::*;

#[frame_support::pallet]
pub mod pallet {
use super::*;
use frame_system::pallet_prelude::*;
use frame_system::{RawOrigin, WeightInfo};
use scale_info::prelude::vec::Vec;

#[pallet::config]
pub trait Config: frame_system::Config {
type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
}

#[pallet::pallet]
pub struct Pallet<T>(_);

#[pallet::event]
#[pallet::generate_deposit(pub(super) fn deposit_event)]
pub enum Event<T: Config> {
/// History was seeded. [who, remark_size]
HistorySeeded { who: T::AccountId, remark_size: u32 },
}

#[pallet::error]
pub enum Error<T> {
/// The sender is not authorized to seed history
NotAuthorized,
}

#[pallet::storage]
#[pallet::getter(fn history_seeder)]
pub type HistorySeeder<T: Config> = StorageValue<_, T::AccountId, OptionQuery>;

#[pallet::call]
impl<T: Config> Pallet<T> {
/// Seed history with a remark
/// TODO: add proper weight
#[pallet::call_index(0)]
#[pallet::weight((<T as frame_system::Config>::SystemWeightInfo::remark(remark.len() as u32) + T::DbWeight::get().reads(1), Pays::No))]
pub fn seed_history(origin: OriginFor<T>, remark: Vec<u8>) -> DispatchResult {
let who = ensure_signed(origin.clone())?;

// Ensure the sender is the authorized history seeder
ensure!(
Some(who.clone()) == Self::history_seeder(),
Error::<T>::NotAuthorized
);

// Add the remark to the block
frame_system::Pallet::<T>::remark(
RawOrigin::Signed(who.clone()).into(),
remark.clone(),
)
.map_err(|e| e.error)?;

// Emit an event
Self::deposit_event(Event::HistorySeeded {
who,
remark_size: remark.len() as u32,
});

Ok(())
}

#[pallet::call_index(1)]
#[pallet::weight(T::DbWeight::get().writes(1))]
pub fn set_history_seeder(
origin: OriginFor<T>,
new_seeder: T::AccountId,
) -> DispatchResult {
ensure_root(origin)?;
HistorySeeder::<T>::put(new_seeder);
Ok(())
}
}

#[derive(frame_support::DefaultNoBound)]
#[pallet::genesis_config]
pub struct GenesisConfig<T: Config> {
pub history_seeder: Option<T::AccountId>,
}

#[pallet::genesis_build]
impl<T: Config> BuildGenesisConfig for GenesisConfig<T> {
fn build(&self) {
if let Some(ref seeder) = self.history_seeder {
HistorySeeder::<T>::put(seeder);
}
}
}
}
106 changes: 106 additions & 0 deletions crates/pallet-history-seeding/src/tests.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
use super::*;
use crate::{self as pallet_history_seeding};
use frame_support::{assert_noop, assert_ok, construct_runtime, derive_impl};
use frame_system as system;
use sp_runtime::BuildStorage;

type Block = frame_system::mocking::MockBlock<Test>;

construct_runtime!(
pub struct Test {
System: frame_system,
Sudo: pallet_sudo,
HistorySeeding: pallet_history_seeding,
}
);

#[derive_impl(frame_system::config_preludes::TestDefaultConfig)]
impl frame_system::Config for Test {
type Block = Block;
}

impl pallet_sudo::Config for Test {
type RuntimeEvent = RuntimeEvent;
type RuntimeCall = RuntimeCall;
type WeightInfo = ();
}

impl pallet::Config for Test {
type RuntimeEvent = RuntimeEvent;
}

pub fn new_test_ext() -> sp_io::TestExternalities {
let t = system::GenesisConfig::<Test>::default()
.build_storage()
.unwrap();
t.into()
}

#[test]
fn genesis_config_works() {
new_test_ext().execute_with(|| {
let genesis_config = pallet::GenesisConfig::<Test> {
history_seeder: Some(1),
};
genesis_config.build();
assert_eq!(HistorySeeding::history_seeder(), Some(1));
});
}

#[test]
fn set_history_seeder_works() {
new_test_ext().execute_with(|| {
assert_ok!(HistorySeeding::set_history_seeder(RuntimeOrigin::root(), 1));
assert_eq!(HistorySeeding::history_seeder(), Some(1));

// Ensure only root can set the history seeder
assert_noop!(
HistorySeeding::set_history_seeder(RuntimeOrigin::signed(1), 2),
sp_runtime::DispatchError::BadOrigin
);
});
}

#[test]
fn seed_history_works() {
new_test_ext().execute_with(|| {
System::set_block_number(1);

// Set the history seeder
assert_ok!(HistorySeeding::set_history_seeder(RuntimeOrigin::root(), 1));

// Seed history
let remark = vec![1, 2, 3];
assert_ok!(HistorySeeding::seed_history(
RuntimeOrigin::signed(1),
remark.clone()
));

// Check if the event was emitted
System::assert_has_event(RuntimeEvent::HistorySeeding(Event::HistorySeeded {
who: 1,
remark_size: 3,
}));

// Ensure unauthorized account cannot seed history
assert_noop!(
HistorySeeding::seed_history(RuntimeOrigin::signed(2), remark),
Error::<Test>::NotAuthorized
);
});
}

#[test]
fn seed_history_fails_when_no_seeder_set() {
new_test_ext().execute_with(|| {
let remark = vec![1, 2, 3];
assert_noop!(
HistorySeeding::seed_history(RuntimeOrigin::signed(1), remark.clone()),
Error::<Test>::NotAuthorized
);
assert_noop!(
HistorySeeding::seed_history(RuntimeOrigin::root(), remark),
sp_runtime::DispatchError::BadOrigin
);
});
}
9 changes: 6 additions & 3 deletions crates/subspace-malicious-operator/src/chain_spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ use std::marker::PhantomData;
use std::num::NonZeroU32;
use subspace_runtime::{
AllowAuthoringBy, CouncilConfig, DemocracyConfig, DomainsConfig, EnableRewardsAt,
MaxDomainBlockSize, MaxDomainBlockWeight, RewardsConfig, RuntimeConfigsConfig, SubspaceConfig,
VestingConfig,
HistorySeedingConfig, MaxDomainBlockSize, MaxDomainBlockWeight, RewardsConfig,
RuntimeConfigsConfig, SubspaceConfig, VestingConfig,
};
use subspace_runtime_primitives::{
AccountId, Balance, BlockNumber, CouncilDemocracyConfigParams, SSC,
Expand Down Expand Up @@ -261,7 +261,7 @@ fn subspace_genesis_config(
raw_genesis_storage: genesis_domain_params.raw_genesis_storage,

// Domain config, mainly for placeholder the concrete value TBD
owner_account_id: sudo_account,
owner_account_id: sudo_account.clone(),
domain_name: genesis_domain_params.domain_name,
max_block_size: MaxDomainBlockSize::get(),
max_block_weight: MaxDomainBlockWeight::get(),
Expand All @@ -274,6 +274,9 @@ fn subspace_genesis_config(
initial_balances: genesis_domain_params.initial_balances,
}],
},
history_seeding: HistorySeedingConfig {
history_seeder: Some(sudo_account),
},
}
}

Expand Down
8 changes: 6 additions & 2 deletions crates/subspace-node/src/chain_spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,9 @@ use std::num::NonZeroU32;
use subspace_core_primitives::PotKey;
use subspace_runtime::{
AllowAuthoringBy, BalancesConfig, CouncilConfig, DemocracyConfig, DomainsConfig,
EnableRewardsAt, MaxDomainBlockSize, MaxDomainBlockWeight, RewardsConfig, RuntimeConfigsConfig,
RuntimeGenesisConfig, SubspaceConfig, SudoConfig, SystemConfig, VestingConfig, WASM_BINARY,
EnableRewardsAt, HistorySeedingConfig, MaxDomainBlockSize, MaxDomainBlockWeight, RewardsConfig,
RuntimeConfigsConfig, RuntimeGenesisConfig, SubspaceConfig, SudoConfig, SystemConfig,
VestingConfig, WASM_BINARY,
};
use subspace_runtime_primitives::time::MILLISECS_PER_BLOCK;
use subspace_runtime_primitives::{
Expand Down Expand Up @@ -469,6 +470,9 @@ fn subspace_genesis_config(
.then_some(genesis_domain_params.permissioned_action_allowed_by),
genesis_domains,
},
history_seeding: HistorySeedingConfig {
history_seeder: Some(sudo_account.clone()),
},
})
}

Expand Down
2 changes: 2 additions & 0 deletions crates/subspace-runtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ pallet-balances = { default-features = false, git = "https://github.com/subspace
pallet-collective = { default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "5626154d0781ac9a6ffd5a6207ed237f425ae631" }
pallet-democracy = { default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "5626154d0781ac9a6ffd5a6207ed237f425ae631" }
pallet-domains = { version = "0.1.0", default-features = false, path = "../pallet-domains" }
pallet-history-seeding = { version = "0.1.0", default-features = false,path = "../pallet-history-seeding" }
pallet-messenger = { version = "0.1.0", path = "../../domains/pallets/messenger", default-features = false }
pallet-mmr = { default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "5626154d0781ac9a6ffd5a6207ed237f425ae631" }
pallet-offences-subspace = { version = "0.1.0", default-features = false, path = "../pallet-offences-subspace" }
Expand Down Expand Up @@ -94,6 +95,7 @@ std = [
"pallet-collective/std",
"pallet-democracy/std",
"pallet-domains/std",
"pallet-history-seeding/std",
"pallet-messenger/std",
"pallet-mmr/std",
"pallet-offences-subspace/std",
Expand Down
7 changes: 7 additions & 0 deletions crates/subspace-runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,10 @@ impl pallet_democracy::Config for Runtime {
type WeightInfo = pallet_democracy::weights::SubstrateWeight<Runtime>;
}

impl pallet_history_seeding::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
}

parameter_types! {
pub const SelfChainId: ChainId = ChainId::Consensus;
}
Expand Down Expand Up @@ -966,6 +970,9 @@ construct_runtime!(
Democracy: pallet_democracy = 83,
Preimage: pallet_preimage = 84,

// history seeding
HistorySeeding: pallet_history_seeding = 91,

// Reserve some room for other pallets as we'll remove sudo pallet eventually.
Sudo: pallet_sudo = 100,
}
Expand Down

0 comments on commit 8a18594

Please sign in to comment.