Skip to content

Commit

Permalink
Remove iterations from PreDigestPotInfo and introduce a few consens…
Browse files Browse the repository at this point in the history
…us log items instead for stateless verification purposes, prepare for future extension for entropy injection into seed too
  • Loading branch information
nazar-pc committed Aug 29, 2023
1 parent f140658 commit d819d2c
Show file tree
Hide file tree
Showing 10 changed files with 313 additions and 62 deletions.
67 changes: 50 additions & 17 deletions crates/pallet-subspace/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ use sp_consensus_slots::Slot;
use sp_consensus_subspace::consensus::verify_solution;
use sp_consensus_subspace::digests::CompatibleDigestItem;
use sp_consensus_subspace::offence::{OffenceDetails, OffenceError, OnOffenceHandler};
#[cfg(feature = "pot")]
use sp_consensus_subspace::PotParameters;
use sp_consensus_subspace::{
ChainConstants, EquivocationProof, FarmerPublicKey, FarmerSignature, SignedVote, Vote,
};
Expand All @@ -65,13 +67,12 @@ use sp_runtime::transaction_validity::{
};
use sp_runtime::DispatchError;
use sp_std::collections::btree_map::BTreeMap;
use sp_std::num::NonZeroU32;
use sp_std::prelude::*;
use subspace_core_primitives::crypto::Scalar;
#[cfg(feature = "pot")]
use subspace_core_primitives::PotProof;
use subspace_core_primitives::{
ArchivedHistorySegment, HistorySize, PublicKey, Randomness, RewardSignature, SectorId,
ArchivedHistorySegment, HistorySize, PotSeed, PublicKey, Randomness, RewardSignature, SectorId,
SectorIndex, SegmentHeader, SegmentIndex, SolutionRange,
};
use subspace_solving::REWARD_SIGNING_CONTEXT;
Expand Down Expand Up @@ -153,7 +154,7 @@ mod pallet {
use sp_std::prelude::*;
use subspace_core_primitives::crypto::Scalar;
use subspace_core_primitives::{
HistorySize, Randomness, SectorIndex, SegmentHeader, SegmentIndex, SolutionRange,
HistorySize, PotSeed, Randomness, SectorIndex, SegmentHeader, SegmentIndex, SolutionRange,
};

pub(super) struct InitialSolutionRanges<T: Config> {
Expand Down Expand Up @@ -333,7 +334,7 @@ mod pallet {
RootPlotPublicKey::<T>::put(root_farmer.clone());
}
}
PotSlotIterations::<T>::put(self.pot_slot_iterations.get());
PotSlotIterations::<T>::put(self.pot_slot_iterations);
}
}

Expand Down Expand Up @@ -381,19 +382,19 @@ mod pallet {

pub(super) struct DefaultPotSlotIterations {}

// TODO: Replace with `NonZeroU32` once we can use it:
// https://github.com/paritytech/parity-scale-codec/pull/505
impl Get<u32> for DefaultPotSlotIterations {
fn get() -> u32 {
unreachable!("Always instantiated during genesis; qed");
impl Get<NonZeroU32> for DefaultPotSlotIterations {
fn get() -> NonZeroU32 {
// TODO: Replace with below panic if/when https://github.com/paritytech/polkadot-sdk/issues/1282
// is resolved upstream
NonZeroU32::MIN
// unreachable!("Always instantiated during genesis; qed");
}
}

/// Number of iterations for proof of time per slot
#[pallet::storage]
// #[pallet::getter(fn pot_slot_iterations)]
pub(super) type PotSlotIterations<T> =
StorageValue<_, u32, ValueQuery, DefaultPotSlotIterations>;
StorageValue<_, NonZeroU32, ValueQuery, DefaultPotSlotIterations>;

/// Solution ranges used for challenges.
#[pallet::storage]
Expand Down Expand Up @@ -501,6 +502,10 @@ mod pallet {
#[pallet::getter(fn root_plot_public_key)]
pub(super) type RootPlotPublicKey<T> = StorageValue<_, FarmerPublicKey>;

/// Future proof of time seed, essentially output of parent block's future proof of time.
#[pallet::storage]
pub(super) type FuturePotSeed<T> = StorageValue<_, PotSeed>;

#[pallet::hooks]
impl<T: Config> Hooks<T::BlockNumber> for Pallet<T> {
fn on_initialize(block_number: T::BlockNumber) -> Weight {
Expand Down Expand Up @@ -795,6 +800,22 @@ impl<T: Config> Pallet<T> {
}

fn do_initialize(block_number: T::BlockNumber) {
#[cfg(feature = "pot")]
frame_system::Pallet::<T>::deposit_log(DigestItem::future_pot_seed(
if block_number.is_one() {
PotSeed::from_genesis_block_hash(
frame_system::Pallet::<T>::block_hash(T::BlockNumber::zero())
.as_ref()
.try_into()
.expect("Genesis block hash length must match, panic otherwise"),
)
} else {
FuturePotSeed::<T>::get().expect(
"Is set at the end of `do_initialize` of every block after genesis; qed",
)
},
));

let pre_digest = <frame_system::Pallet<T>>::digest()
.logs
.iter()
Expand Down Expand Up @@ -930,6 +951,15 @@ impl<T: Config> Pallet<T> {
next_global_randomness,
));
}

#[cfg(feature = "pot")]
frame_system::Pallet::<T>::deposit_log(DigestItem::pot_slot_iterations(
PotSlotIterations::<T>::get(),
));
// TODO: Once we have entropy injection, it might take effect right here and should be
// accounted for
#[cfg(feature = "pot")]
FuturePotSeed::<T>::put(pre_digest.pot_info().future_proof_of_time().seed());
}

fn do_finalize(_block_number: T::BlockNumber) {
Expand Down Expand Up @@ -1083,12 +1113,15 @@ impl<T: Config> Pallet<T> {
Some(())
}

/// Number of iterations for proof of time per slot
// TODO: Remove once we can use `NonZeroU32` directly:
// https://github.com/paritytech/parity-scale-codec/pull/505
pub fn pot_slot_iterations() -> NonZeroU32 {
NonZeroU32::new(PotSlotIterations::<T>::get())
.expect("Always initialized to non-zero value; qed")
/// Proof of time parameters
#[cfg(feature = "pot")]
pub fn pot_parameters() -> PotParameters {
PotParameters::V0 {
iterations: PotSlotIterations::<T>::get(),
// TODO: This is where adjustment for number of iterations and entropy injection will
// happen for runtime API calls
next_change: None,
}
}

/// Check if `farmer_public_key` is in block list (due to equivocation)
Expand Down
2 changes: 1 addition & 1 deletion crates/pallet-subspace/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ pub fn make_pre_digest(
slot,
solution,
#[cfg(feature = "pot")]
pot_info: PreDigestPotInfo::Regular {
pot_info: PreDigestPotInfo::V0 {
iterations: NonZeroU32::new(100_000).unwrap(),
proof_of_time: Default::default(),
future_proof_of_time: Default::default(),
Expand Down
5 changes: 1 addition & 4 deletions crates/sc-consensus-subspace/src/slot_worker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -297,8 +297,6 @@ where
let (solution_range, voting_solution_range) =
extract_solution_ranges_for_block(self.client.as_ref(), parent_hash).ok()?;

#[cfg(feature = "pot")]
let pot_slot_iterations = runtime_api.pot_slot_iterations(parent_hash).ok()?;
let maybe_root_plot_public_key = runtime_api.root_plot_public_key(parent_hash).ok()?;

#[cfg(feature = "pot")]
Expand Down Expand Up @@ -471,8 +469,7 @@ where
slot,
solution,
#[cfg(feature = "pot")]
pot_info: PreDigestPotInfo::Regular {
iterations: pot_slot_iterations,
pot_info: PreDigestPotInfo::V0 {
proof_of_time,
future_proof_of_time,
},
Expand Down
4 changes: 3 additions & 1 deletion crates/sc-proof-of-time/src/source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,9 @@ where
#[cfg(feature = "pot")]
let runtime_api = client.runtime_api();
#[cfg(feature = "pot")]
let iterations = runtime_api.pot_slot_iterations(best_hash)?;
let iterations = runtime_api
.pot_parameters(best_hash)?
.iterations(Slot::from(start_slot));
#[cfg(not(feature = "pot"))]
let iterations = NonZeroU32::new(100_000_000).expect("Not zero; qed");

Expand Down
Loading

0 comments on commit d819d2c

Please sign in to comment.