Skip to content

Commit

Permalink
Merge pull request #2391 from subspace/enable-rewards-at-solution-range
Browse files Browse the repository at this point in the history
Support enabling rewards at solution range (either in chain spec or with an extrinsic)
  • Loading branch information
nazar-pc authored Jan 5, 2024
2 parents 626fb15 + fae3dfc commit 4146744
Show file tree
Hide file tree
Showing 9 changed files with 171 additions and 40 deletions.
9 changes: 6 additions & 3 deletions crates/pallet-subspace/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use frame_benchmarking::v2::*;
#[benchmarks]
mod benchmarks {
use crate::{
AllowAuthoringByAnyone, Call, Config, CurrentSlot, EnableRewards,
AllowAuthoringByAnyone, Call, Config, CurrentSlot, EnableRewards, EnableRewardsAt,
NextSolutionRangeOverride, Pallet, SegmentCommitment, ShouldAdjustSolutionRange,
SolutionRanges,
};
Expand Down Expand Up @@ -123,11 +123,14 @@ mod benchmarks {
}

#[benchmark]
fn enable_rewards() {
fn enable_rewards_at() {
EnableRewards::<T>::take();

#[extrinsic_call]
_(RawOrigin::Root, Some(100u32.into()));
_(
RawOrigin::Root,
EnableRewardsAt::Height(Some(100u32.into())),
);

assert_eq!(EnableRewards::<T>::get(), Some(100u32.into()));
}
Expand Down
91 changes: 77 additions & 14 deletions crates/pallet-subspace/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -263,10 +263,25 @@ pub mod pallet {
pub(super) entropy: Blake3Hash,
}

/// When to enable block/vote rewards
#[derive(Debug, Copy, Clone, Eq, PartialEq, Encode, Decode, TypeInfo)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum EnableRewardsAt<BlockNumber> {
/// At specified height or next block if `None`
Height(Option<BlockNumber>),
/// When solution range is below specified threshold
SolutionRange(u64),
/// Manually with an explicit extrinsic
Manually,
}

#[pallet::genesis_config]
pub struct GenesisConfig<T> {
/// Whether rewards should be enabled.
pub enable_rewards: bool,
pub struct GenesisConfig<T>
where
T: Config,
{
/// When rewards should be enabled.
pub enable_rewards_at: EnableRewardsAt<BlockNumberFor<T>>,
/// Whether storage access should be enabled.
pub enable_storage_access: bool,
/// Who can author blocks at genesis.
Expand All @@ -277,7 +292,10 @@ pub mod pallet {
pub phantom: PhantomData<T>,
}

impl<T> Default for GenesisConfig<T> {
impl<T> Default for GenesisConfig<T>
where
T: Config,
{
#[inline]
#[track_caller]
fn default() -> Self {
Expand All @@ -288,10 +306,23 @@ pub mod pallet {
}

#[pallet::genesis_build]
impl<T: Config> BuildGenesisConfig for GenesisConfig<T> {
impl<T> BuildGenesisConfig for GenesisConfig<T>
where
T: Config,
{
fn build(&self) {
if self.enable_rewards {
EnableRewards::<T>::put::<BlockNumberFor<T>>(sp_runtime::traits::One::one());
match self.enable_rewards_at {
EnableRewardsAt::Height(maybe_block_number) => {
EnableRewards::<T>::put(
maybe_block_number.unwrap_or_else(sp_runtime::traits::One::one),
);
}
EnableRewardsAt::SolutionRange(solution_range) => {
EnableRewardsBelowSolutionRange::<T>::put(solution_range);
}
EnableRewardsAt::Manually => {
// Nothing to do in this case
}
}
IsStorageAccessEnabled::<T>::put(self.enable_storage_access);
match &self.allow_authoring_by {
Expand Down Expand Up @@ -409,6 +440,10 @@ pub mod pallet {
#[pallet::storage]
pub(super) type EnableRewards<T: Config> = StorageValue<_, BlockNumberFor<T>>;

/// Enable rewards when solution range is below this threshold.
#[pallet::storage]
pub(super) type EnableRewardsBelowSolutionRange<T: Config> = StorageValue<_, u64>;

/// Temporary value (cleared at block finalization) with block author information.
#[pallet::storage]
pub(super) type CurrentBlockAuthorInfo<T: Config> = StorageValue<
Expand Down Expand Up @@ -558,13 +593,13 @@ pub mod pallet {
/// Enable rewards for blocks and votes at specified block height.
#[pallet::call_index(4)]
#[pallet::weight(<T as Config>::WeightInfo::enable_rewards())]
pub fn enable_rewards(
pub fn enable_rewards_at(
origin: OriginFor<T>,
height: Option<BlockNumberFor<T>>,
enable_rewards_at: EnableRewardsAt<BlockNumberFor<T>>,
) -> DispatchResult {
ensure_root(origin)?;

Self::do_enable_rewards(height)
Self::do_enable_rewards_at(enable_rewards_at)
}

/// Enable storage access for all users.
Expand Down Expand Up @@ -732,6 +767,16 @@ impl<T: Config> Pallet<T> {
solution_ranges
.voting_next
.replace(next_voting_solution_range);

if let Some(solution_range_for_rewards) = EnableRewardsBelowSolutionRange::<T>::get() {
if next_solution_range <= solution_range_for_rewards {
EnableRewardsBelowSolutionRange::<T>::take();

let next_block_number =
frame_system::Pallet::<T>::current_block_number() + One::one();
EnableRewards::<T>::put(next_block_number);
}
}
});

EraStartSlot::<T>::put(current_slot);
Expand Down Expand Up @@ -1059,14 +1104,32 @@ impl<T: Config> Pallet<T> {
}
}

fn do_enable_rewards(height: Option<BlockNumberFor<T>>) -> DispatchResult {
fn do_enable_rewards_at(
enable_rewards_at: EnableRewardsAt<BlockNumberFor<T>>,
) -> DispatchResult {
if EnableRewards::<T>::get().is_some() {
return Err(Error::<T>::RewardsAlreadyEnabled.into());
}

// Enable rewards at a particular block height (default to the next block after this)
let next_block_number = frame_system::Pallet::<T>::current_block_number() + One::one();
EnableRewards::<T>::put(height.unwrap_or(next_block_number).max(next_block_number));
match enable_rewards_at {
EnableRewardsAt::Height(maybe_block_number) => {
// Enable rewards at a particular block height (default to the next block after
// this)
let next_block_number =
frame_system::Pallet::<T>::current_block_number() + One::one();
EnableRewards::<T>::put(
maybe_block_number
.unwrap_or(next_block_number)
.max(next_block_number),
);
}
EnableRewardsAt::SolutionRange(solution_range) => {
EnableRewardsBelowSolutionRange::<T>::put(solution_range);
}
EnableRewardsAt::Manually => {
// Nothing to do in this case
}
}

Ok(())
}
Expand Down
6 changes: 3 additions & 3 deletions crates/pallet-subspace/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
use crate::equivocation::EquivocationHandler;
use crate::{
self as pallet_subspace, AllowAuthoringBy, Config, CurrentSlot, FarmerPublicKey,
NormalEraChange,
self as pallet_subspace, AllowAuthoringBy, Config, CurrentSlot, EnableRewardsAt,
FarmerPublicKey, NormalEraChange,
};
use frame_support::parameter_types;
use frame_support::traits::{ConstU128, ConstU16, ConstU32, ConstU64, OnInitialize};
Expand Down Expand Up @@ -297,7 +297,7 @@ pub fn new_test_ext(pot_extension: PotExtension) -> TestExternalities {
.unwrap();

pallet_subspace::GenesisConfig::<Test> {
enable_rewards: true,
enable_rewards_at: EnableRewardsAt::Height(Some(1)),
enable_storage_access: true,
allow_authoring_by: AllowAuthoringBy::Anyone,
pot_slot_iterations: NonZeroU32::new(100_000).unwrap(),
Expand Down
66 changes: 63 additions & 3 deletions crates/pallet-subspace/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ use crate::mock::{
};
use crate::{
pallet, AllowAuthoringByAnyone, BlockList, Call, CheckVoteError, Config,
CurrentBlockAuthorInfo, CurrentBlockVoters, CurrentSlot, ParentBlockAuthorInfo,
ParentBlockVoters, SegmentCommitment, SubspaceEquivocationOffence,
CurrentBlockAuthorInfo, CurrentBlockVoters, CurrentSlot, EnableRewardsAt,
ParentBlockAuthorInfo, ParentBlockVoters, SegmentCommitment, SubspaceEquivocationOffence,
};
use codec::Encode;
use frame_support::dispatch::{GetDispatchInfo, Pays};
Expand Down Expand Up @@ -1600,7 +1600,12 @@ fn enabling_block_rewards_works() {
assert_eq!(Subspace::find_voting_reward_addresses().len(), 0);

// Enable since next block only rewards
crate::EnableRewards::<Test>::put(frame_system::Pallet::<Test>::current_block_number() + 1);
assert_ok!(Subspace::enable_rewards_at(
RuntimeOrigin::root(),
EnableRewardsAt::Height(Some(
frame_system::Pallet::<Test>::current_block_number() + 1,
)),
));
// No rewards yet
assert_matches!(Subspace::find_block_reward_address(), None);
assert_eq!(Subspace::find_voting_reward_addresses().len(), 0);
Expand All @@ -1618,6 +1623,61 @@ fn enabling_block_rewards_works() {
});
}

#[test]
fn enabling_block_rewards_at_solution_range_works() {
new_test_ext(allow_all_pot_extension()).execute_with(|| {
let keypair = Keypair::generate();

assert_eq!(<Test as Config>::EraDuration::get(), 4);
assert_eq!(
<Test as Config>::InitialSolutionRange::get(),
INITIAL_SOLUTION_RANGE
);
let initial_solution_ranges = SolutionRanges {
current: INITIAL_SOLUTION_RANGE,
next: None,
voting_current: INITIAL_SOLUTION_RANGE,
voting_next: None,
};
assert_eq!(Subspace::solution_ranges(), initial_solution_ranges);
// enable solution range adjustment
assert_ok!(Subspace::enable_solution_range_adjustment(
RuntimeOrigin::root(),
None,
None
));
// Disable rewards
crate::EnableRewards::<Test>::take();
// Enable rewards below current solution range
assert_ok!(Subspace::enable_rewards_at(
RuntimeOrigin::root(),
EnableRewardsAt::SolutionRange(INITIAL_SOLUTION_RANGE - 1),
));

// Progress to almost era edge
progress_to_block(&keypair, 3, 1);
// No solution range update
assert_eq!(Subspace::solution_ranges(), initial_solution_ranges);
// Rewards are not enabled
assert_eq!(crate::EnableRewards::<Test>::get(), None);

// Era edge
progress_to_block(&keypair, 4, 1);
// Next solution range should be updated, but current is still unchanged
let updated_solution_ranges = Subspace::solution_ranges();
assert_eq!(
updated_solution_ranges.current,
initial_solution_ranges.current
);
assert!(updated_solution_ranges.next.is_some());
// Rewards will be enabled in the next block
assert_eq!(
crate::EnableRewards::<Test>::get(),
Some(frame_system::Pallet::<Test>::current_block_number() + 1)
);
})
}

#[test]
fn allow_authoring_by_anyone_works() {
new_test_ext(allow_all_pot_extension()).execute_with(|| {
Expand Down
7 changes: 6 additions & 1 deletion crates/sp-domains/src/proof_provider_and_verifier.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
use frame_support::PalletError;
use hash_db::Hasher;
use parity_scale_codec::{Codec, Compact, Decode, Encode};
#[cfg(feature = "std")]
use parity_scale_codec::Codec;
use parity_scale_codec::{Compact, Decode, Encode};
use scale_info::TypeInfo;
use sp_core::storage::StorageKey;
#[cfg(feature = "std")]
use sp_state_machine::prove_read;
#[cfg(feature = "std")]
use sp_state_machine::TrieBackendBuilder;
use sp_std::fmt::Debug;
use sp_std::marker::PhantomData;
use sp_std::vec::Vec;
use sp_trie::{read_trie_value, LayoutV1, StorageProof};
#[cfg(feature = "std")]
use trie_db::{DBValue, TrieDBMutBuilder, TrieLayout, TrieMut};

/// Verification error.
Expand Down Expand Up @@ -59,6 +63,7 @@ impl<H: Hasher> StorageProofVerifier<H> {
}
}

#[cfg(feature = "std")]
type MemoryDB<T> = memory_db::MemoryDB<
<T as TrieLayout>::Hash,
memory_db::HashKey<<T as TrieLayout>::Hash>,
Expand Down
20 changes: 10 additions & 10 deletions crates/subspace-node/src/chain_spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ use std::marker::PhantomData;
use std::num::NonZeroU32;
use subspace_core_primitives::PotKey;
use subspace_runtime::{
AllowAuthoringBy, BalancesConfig, DomainsConfig, MaxDomainBlockSize, MaxDomainBlockWeight,
RuntimeConfigsConfig, RuntimeGenesisConfig, SubspaceConfig, SudoConfig, SystemConfig,
VestingConfig, MILLISECS_PER_BLOCK, WASM_BINARY,
AllowAuthoringBy, BalancesConfig, DomainsConfig, EnableRewardsAt, MaxDomainBlockSize,
MaxDomainBlockWeight, RuntimeConfigsConfig, RuntimeGenesisConfig, SubspaceConfig, SudoConfig,
SystemConfig, VestingConfig, MILLISECS_PER_BLOCK, WASM_BINARY,
};
use subspace_runtime_primitives::{AccountId, Balance, BlockNumber, SSC};

Expand Down Expand Up @@ -97,7 +97,7 @@ const TOKEN_GRANTS: &[(&str, u128)] = &[

/// Additional subspace specific genesis parameters.
struct GenesisParams {
enable_rewards: bool,
enable_rewards_at: EnableRewardsAt<BlockNumber>,
enable_storage_access: bool,
allow_authoring_by: AllowAuthoringBy,
pot_slot_iterations: NonZeroU32,
Expand Down Expand Up @@ -168,7 +168,7 @@ pub fn gemini_3g_compiled() -> Result<ConsensusChainSpec<RuntimeGenesisConfig>,
balances,
vesting_schedules,
GenesisParams {
enable_rewards: false,
enable_rewards_at: EnableRewardsAt::Manually,
enable_storage_access: true,
allow_authoring_by: AllowAuthoringBy::RootFarmer(
FarmerPublicKey::unchecked_from(hex_literal::hex!(
Expand Down Expand Up @@ -281,7 +281,7 @@ pub fn devnet_config_compiled() -> Result<ConsensusChainSpec<RuntimeGenesisConfi
balances,
vesting_schedules,
GenesisParams {
enable_rewards: false,
enable_rewards_at: EnableRewardsAt::Manually,
enable_storage_access: true,
allow_authoring_by: AllowAuthoringBy::FirstFarmer,
pot_slot_iterations: NonZeroU32::new(150_000_000).expect("Not zero; qed"),
Expand Down Expand Up @@ -346,7 +346,7 @@ pub fn dev_config() -> Result<ConsensusChainSpec<RuntimeGenesisConfig>, String>
],
vec![],
GenesisParams {
enable_rewards: false,
enable_rewards_at: EnableRewardsAt::Manually,
enable_storage_access: true,
allow_authoring_by: AllowAuthoringBy::Anyone,
pot_slot_iterations: NonZeroU32::new(100_000_000).expect("Not zero; qed"),
Expand Down Expand Up @@ -414,7 +414,7 @@ pub fn local_config() -> Result<ConsensusChainSpec<RuntimeGenesisConfig>, String
],
vec![],
GenesisParams {
enable_rewards: false,
enable_rewards_at: EnableRewardsAt::Manually,
enable_storage_access: true,
allow_authoring_by: AllowAuthoringBy::Anyone,
pot_slot_iterations: NonZeroU32::new(100_000_000).expect("Not zero; qed"),
Expand Down Expand Up @@ -462,7 +462,7 @@ fn subspace_genesis_config(
genesis_domain_params: GenesisDomainParams,
) -> RuntimeGenesisConfig {
let GenesisParams {
enable_rewards,
enable_rewards_at,
enable_storage_access,
allow_authoring_by,
pot_slot_iterations,
Expand Down Expand Up @@ -493,7 +493,7 @@ fn subspace_genesis_config(
key: Some(sudo_account.clone()),
},
subspace: SubspaceConfig {
enable_rewards,
enable_rewards_at,
enable_storage_access,
allow_authoring_by,
pot_slot_iterations,
Expand Down
2 changes: 1 addition & 1 deletion crates/subspace-runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ use frame_support::weights::{ConstantMultiplier, IdentityFee, Weight};
use frame_support::{construct_runtime, parameter_types, PalletId};
use frame_system::limits::{BlockLength, BlockWeights};
use frame_system::EnsureNever;
pub use pallet_subspace::AllowAuthoringBy;
pub use pallet_subspace::{AllowAuthoringBy, EnableRewardsAt};
use pallet_transporter::EndpointHandler;
use scale_info::TypeInfo;
use sp_api::{impl_runtime_apis, BlockT};
Expand Down
Loading

0 comments on commit 4146744

Please sign in to comment.