Skip to content

Commit

Permalink
Merge pull request #1884 from subspace/pot-slot-worker
Browse files Browse the repository at this point in the history
PoT slot worker
  • Loading branch information
nazar-pc authored Aug 28, 2023
2 parents 0117e95 + 3b57498 commit ca9406e
Show file tree
Hide file tree
Showing 39 changed files with 1,658 additions and 632 deletions.
7 changes: 7 additions & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions crates/pallet-subspace/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ subspace-proof-of-space = { version = "0.1.0", path = "../subspace-proof-of-spac
default = ["std"]
pot = [
"sp-consensus-subspace/pot",
"subspace-verification/pot",
]
std = [
"codec/std",
Expand Down
54 changes: 47 additions & 7 deletions crates/pallet-subspace/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,10 @@ extern crate alloc;

pub mod equivocation;

#[cfg(test)]
// TODO: Unlock tests for PoT as well once PoT implementation settled
#[cfg(all(test, not(feature = "pot")))]
mod mock;
#[cfg(test)]
#[cfg(all(test, not(feature = "pot")))]
mod tests;

#[cfg(feature = "runtime-benchmarks")]
Expand All @@ -37,7 +38,9 @@ use codec::{Decode, Encode, MaxEncodedLen};
use core::num::NonZeroU64;
use equivocation::{HandleEquivocation, SubspaceEquivocationOffence};
use frame_support::dispatch::{DispatchResult, DispatchResultWithPostInfo, Pays};
use frame_support::traits::{Get, OnTimestampSet};
use frame_support::traits::Get;
#[cfg(not(feature = "pot"))]
use frame_support::traits::OnTimestampSet;
use frame_system::offchain::{SendTransactionTypes, SubmitTransaction};
use log::{debug, error, warn};
pub use pallet::*;
Expand All @@ -51,7 +54,11 @@ use sp_consensus_subspace::{
ChainConstants, EquivocationProof, FarmerPublicKey, FarmerSignature, SignedVote, Vote,
};
use sp_runtime::generic::DigestItem;
use sp_runtime::traits::{BlockNumberProvider, Hash, One, SaturatedConversion, Saturating, Zero};
#[cfg(not(feature = "pot"))]
use sp_runtime::traits::Hash;
use sp_runtime::traits::{BlockNumberProvider, One, Zero};
#[cfg(not(feature = "pot"))]
use sp_runtime::traits::{SaturatedConversion, Saturating};
use sp_runtime::transaction_validity::{
InvalidTransaction, TransactionPriority, TransactionSource, TransactionValidity,
TransactionValidityError, ValidTransaction,
Expand All @@ -60,14 +67,17 @@ use sp_runtime::DispatchError;
use sp_std::collections::btree_map::BTreeMap;
use sp_std::prelude::*;
use subspace_core_primitives::crypto::Scalar;
#[cfg(feature = "pot")]
use subspace_core_primitives::PotCheckpoint;
use subspace_core_primitives::{
ArchivedHistorySegment, HistorySize, PublicKey, Randomness, RewardSignature, SectorId,
SectorIndex, SegmentHeader, SegmentIndex, SolutionRange,
};
use subspace_solving::REWARD_SIGNING_CONTEXT;
#[cfg(not(feature = "pot"))]
use subspace_verification::derive_randomness;
use subspace_verification::{
check_reward_signature, derive_next_solution_range, derive_randomness, PieceCheckParams,
VerifySolutionParams,
check_reward_signature, derive_next_solution_range, PieceCheckParams, VerifySolutionParams,
};

/// Trigger global randomness every interval.
Expand All @@ -79,8 +89,10 @@ pub trait GlobalRandomnessIntervalTrigger {

/// A type signifying to Subspace that it should perform a global randomness update with an internal
/// trigger.
// TODO: Remove when switching to PoT by default
pub struct NormalGlobalRandomnessInterval;

// TODO: Remove when switching to PoT by default
impl GlobalRandomnessIntervalTrigger for NormalGlobalRandomnessInterval {
fn trigger<T: Config>(block_number: T::BlockNumber, por_randomness: Randomness) {
if <Pallet<T>>::should_update_global_randomness(block_number) {
Expand Down Expand Up @@ -184,8 +196,13 @@ mod pallet {

/// The amount of time, in blocks, between updates of global randomness.
#[pallet::constant]
// TODO: Remove when switching to PoT by default
type GlobalRandomnessUpdateInterval: Get<Self::BlockNumber>;

/// The amount of time, in blocks, between updates of global randomness.
#[pallet::constant]
type BlockAuthoringDelay: Get<Slot>;

/// The amount of time, in blocks, that each era should last.
/// NOTE: Currently it is not possible to change the era duration after
/// the chain has started. Attempting to do so will brick block production.
Expand Down Expand Up @@ -355,6 +372,7 @@ mod pallet {
/// Global randomnesses derived from from PoR signature and used for deriving global challenges.
#[pallet::storage]
#[pallet::getter(fn global_randomnesses)]
#[cfg(not(feature = "pot"))]
pub(super) type GlobalRandomnesses<T> =
StorageValue<_, sp_consensus_subspace::GlobalRandomnesses, ValueQuery>;

Expand Down Expand Up @@ -676,6 +694,7 @@ mod pallet {

impl<T: Config> Pallet<T> {
/// Determine the Subspace slot duration based on the Timestamp module configuration.
#[cfg(not(feature = "pot"))]
pub fn slot_duration() -> T::Moment {
// we double the minimum block-period so each author can always propose within
// the majority of their slot.
Expand All @@ -691,6 +710,7 @@ impl<T: Config> Pallet<T> {

/// Determine whether a randomness update should take place at this block.
/// Assumes that initialization has already taken place.
// TODO: Remove when switching to PoT by default
fn should_update_global_randomness(block_number: T::BlockNumber) -> bool {
block_number % T::GlobalRandomnessUpdateInterval::get() == Zero::zero()
}
Expand All @@ -703,7 +723,10 @@ impl<T: Config> Pallet<T> {

/// DANGEROUS: Enact update of global randomness. Should be done on every block where `should_update_global_randomness`
/// has returned `true`, and the caller is the only caller of this function.
// TODO: Remove when switching to PoT by default
#[cfg_attr(feature = "pot", allow(unused_variables))]
fn enact_update_global_randomness(_block_number: T::BlockNumber, por_randomness: Randomness) {
#[cfg(not(feature = "pot"))]
GlobalRandomnesses::<T>::mutate(|global_randomnesses| {
global_randomnesses.next = Some(por_randomness);
});
Expand Down Expand Up @@ -859,11 +882,14 @@ impl<T: Config> Pallet<T> {
}

// Extract PoR randomness from pre-digest.
#[cfg(not(feature = "pot"))]
let por_randomness = derive_randomness(&pre_digest.solution, pre_digest.slot.into());
// Store PoR randomness for block duration as it might be useful.
#[cfg(not(feature = "pot"))]
PorRandomness::<T>::put(por_randomness);

// Deposit global randomness data such that light client can validate blocks later.
#[cfg(not(feature = "pot"))]
frame_system::Pallet::<T>::deposit_log(DigestItem::global_randomness(
GlobalRandomnesses::<T>::get().current,
));
Expand Down Expand Up @@ -897,6 +923,7 @@ impl<T: Config> Pallet<T> {
));
}

#[cfg(not(feature = "pot"))]
PorRandomness::<T>::take();

if let Some((public_key, sector_index, scalar, audit_chunk_offset, slot, _reward_address)) =
Expand Down Expand Up @@ -1054,9 +1081,12 @@ impl<T: Config> Pallet<T> {
confirmation_depth_k: T::ConfirmationDepthK::get()
.try_into()
.unwrap_or_else(|_| panic!("Block number always fits in BlockNumber; qed")),
#[cfg(not(feature = "pot"))]
global_randomness_interval: T::GlobalRandomnessUpdateInterval::get()
.try_into()
.unwrap_or_else(|_| panic!("Block number always fits in BlockNumber; qed")),
#[cfg(feature = "pot")]
block_authoring_delay: T::BlockAuthoringDelay::get(),
era_duration: T::EraDuration::get()
.try_into()
.unwrap_or_else(|_| panic!("Block number always fits in BlockNumber; qed")),
Expand Down Expand Up @@ -1176,17 +1206,21 @@ impl<T: Config> Pallet<T> {
/// initialization has already happened) or from `validate_unsigned` by transaction pool (meaning
/// block initialization didn't happen yet).
fn current_vote_verification_data<T: Config>(is_block_initialized: bool) -> VoteVerificationData {
// TODO: factor PoT in the vote process.
#[cfg(not(feature = "pot"))]
let global_randomnesses = GlobalRandomnesses::<T>::get();
let solution_ranges = SolutionRanges::<T>::get();
VoteVerificationData {
#[cfg(not(feature = "pot"))]
global_randomness: if is_block_initialized {
global_randomnesses.current
} else {
global_randomnesses
.next
.unwrap_or(global_randomnesses.current)
},
// TODO: This is invalid and must be fixed for PoT
#[cfg(feature = "pot")]
global_randomness: Default::default(),
solution_range: if is_block_initialized {
solution_ranges.voting_current
} else {
Expand Down Expand Up @@ -1409,7 +1443,11 @@ fn check_vote<T: Config>(
solution.into(),
slot.into(),
(&VerifySolutionParams {
#[cfg(not(feature = "pot"))]
global_randomness: vote_verification_data.global_randomness,
// TODO: This is incorrect, find a way to verify votes
#[cfg(feature = "pot")]
proof_of_time: PotCheckpoint::default(),
solution_range: vote_verification_data.solution_range,
piece_check_params: Some(PieceCheckParams {
max_pieces_in_sector: T::MaxPiecesInSector::get(),
Expand Down Expand Up @@ -1559,6 +1597,7 @@ fn check_segment_headers<T: Config>(
Ok(())
}

#[cfg(not(feature = "pot"))]
impl<T: Config> OnTimestampSet<T::Moment> for Pallet<T> {
fn on_timestamp_set(moment: T::Moment) {
let slot_duration = Self::slot_duration();
Expand Down Expand Up @@ -1618,6 +1657,7 @@ impl<T: Config> subspace_runtime_primitives::FindVotingRewardAddresses<T::Accoun
}
}

#[cfg(not(feature = "pot"))]
impl<T: Config> frame_support::traits::Randomness<T::Hash, T::BlockNumber> for Pallet<T> {
fn random(subject: &[u8]) -> (T::Hash, T::BlockNumber) {
let mut subject = subject.to_vec();
Expand Down
11 changes: 10 additions & 1 deletion crates/pallet-subspace/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ use subspace_core_primitives::crypto::Scalar;
use subspace_core_primitives::{
ArchivedBlockProgress, ArchivedHistorySegment, Blake2b256Hash, HistorySize, LastArchivedBlock,
Piece, PieceOffset, PublicKey, Randomness, RecordedHistorySegment, SegmentCommitment,
SegmentHeader, SegmentIndex, Solution, SolutionRange,
SegmentHeader, SegmentIndex, SlotNumber, Solution, SolutionRange,
};
use subspace_erasure_coding::ErasureCoding;
use subspace_farmer_components::auditing::audit_sector;
Expand Down Expand Up @@ -121,7 +121,10 @@ where

impl pallet_timestamp::Config for Test {
type Moment = u64;
#[cfg(not(feature = "pot"))]
type OnTimestampSet = Subspace;
#[cfg(feature = "pot")]
type OnTimestampSet = ();
type MinimumPeriod = ConstU64<1>;
type WeightInfo = ();
}
Expand Down Expand Up @@ -154,7 +157,9 @@ pub const INITIAL_SOLUTION_RANGE: SolutionRange =
u64::MAX / (1024 * 1024 * 1024 / Piece::SIZE as u64) * SLOT_PROBABILITY.0 / SLOT_PROBABILITY.1;

parameter_types! {
#[cfg(not(feature = "pot"))]
pub const GlobalRandomnessUpdateInterval: u64 = 10;
pub const BlockAuthoringDelay: SlotNumber = 2;
pub const EraDuration: u32 = 4;
// 1GB
pub const InitialSolutionRange: SolutionRange = INITIAL_SOLUTION_RANGE;
Expand All @@ -176,6 +181,7 @@ parameter_types! {
impl Config for Test {
type RuntimeEvent = RuntimeEvent;
type GlobalRandomnessUpdateInterval = GlobalRandomnessUpdateInterval;
type BlockAuthoringDelay = BlockAuthoringDelay;
type EraDuration = EraDuration;
type InitialSolutionRange = InitialSolutionRange;
type SlotProbability = SlotProbability;
Expand Down Expand Up @@ -259,6 +265,8 @@ pub fn make_pre_digest(
solution,
#[cfg(feature = "pot")]
proof_of_time: Default::default(),
#[cfg(feature = "pot")]
future_proof_of_time: Default::default(),
});
Digest { logs: vec![log] }
}
Expand Down Expand Up @@ -327,6 +335,7 @@ pub fn generate_equivocation_proof(
System::reset_events();
System::initialize(&current_block, &parent_hash, &pre_digest);
System::set_block_number(current_block);
#[cfg(not(feature = "pot"))]
Timestamp::set_timestamp(*current_slot * Subspace::slot_duration());
System::finalize()
};
Expand Down
4 changes: 3 additions & 1 deletion crates/pallet-subspace/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@ use frame_support::{assert_err, assert_ok};
use frame_system::{EventRecord, Phase};
use schnorrkel::Keypair;
use sp_consensus_slots::Slot;
use sp_consensus_subspace::{FarmerPublicKey, FarmerSignature, GlobalRandomnesses, SolutionRanges};
#[cfg(not(feature = "pot"))]
use sp_consensus_subspace::GlobalRandomnesses;
use sp_consensus_subspace::{FarmerPublicKey, FarmerSignature, SolutionRanges};
use sp_core::crypto::UncheckedFrom;
use sp_runtime::traits::{BlockNumberProvider, Header};
use sp_runtime::transaction_validity::{
Expand Down
7 changes: 7 additions & 0 deletions crates/sc-consensus-subspace-rpc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ async-oneshot = "0.5.0"
futures = "0.3.28"
futures-timer = "3.0.2"
jsonrpsee = { version = "0.16.2", features = ["server", "macros"] }
lru = "0.10.0"
parity-scale-codec = "3.6.3"
parking_lot = "0.12.1"
sc-client-api = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "55c157cff49b638a59d81a9f971f0f9a66829c71" }
Expand All @@ -37,3 +38,9 @@ subspace-farmer-components = { version = "0.1.0", path = "../subspace-farmer-com
subspace-networking = { version = "0.1.0", path = "../subspace-networking" }
subspace-rpc-primitives = { version = "0.1.0", path = "../subspace-rpc-primitives" }
tracing = "0.1.37"

[features]
pot = [
"sc-consensus-subspace/pot",
"sp-consensus-subspace/pot",
]
Loading

0 comments on commit ca9406e

Please sign in to comment.