Skip to content

Commit

Permalink
Refactor PoT initialization to use initial key, not create special ca…
Browse files Browse the repository at this point in the history
…se `PotPreDigest` variants and tweak TimeKeeper initialization to not wait for blocks being produced
  • Loading branch information
nazar-pc committed Aug 22, 2023
1 parent 3e0492b commit 0ac040d
Show file tree
Hide file tree
Showing 7 changed files with 177 additions and 237 deletions.
1 change: 0 additions & 1 deletion crates/pallet-subspace/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -864,7 +864,6 @@ impl<T: Config> Pallet<T> {
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
33 changes: 14 additions & 19 deletions crates/sc-consensus-subspace/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,16 +102,6 @@ pub enum PotVerifyError {
slot_number: SlotNumber,
},

/// Parent block has no proof of time digest.
#[error(
"Parent block missing proof of time : {block_number}/{parent_slot_number}/{slot_number}"
)]
ParentMissingPotDigest {
block_number: BlockNumber,
parent_slot_number: SlotNumber,
slot_number: SlotNumber,
},

/// Verification failed.
#[error("Proof of time error: {0}")]
PotVerifyBlockProofsError(#[from] PotVerifyBlockProofsError),
Expand Down Expand Up @@ -1011,6 +1001,9 @@ where
};

if subspace_digest_items.global_randomness != correct_global_randomness {
// TODO: There is some kind of mess with PoT randomness right now that doesn't make a
// lot of sense, restore this check once that is resolved
#[cfg(not(feature = "pot"))]
return Err(Error::InvalidGlobalRandomness(block_hash));
}

Expand Down Expand Up @@ -1158,21 +1151,23 @@ where
None => return Ok(randomness),
};

let parent_pot_digest = parent_pre_digest.proof_of_time.as_ref().ok_or_else(|| {
PotVerifyError::ParentMissingPotDigest {
block_number: block_number.into(),
parent_slot_number: parent_pre_digest.slot.into(),
slot_number: pre_digest.slot.into(),
}
})?;
let maybe_parent_pot_digest = &parent_pre_digest.proof_of_time;

proof_of_time
.verify_block_proofs(
block_number.into(),
pre_digest.slot.into(),
// TODO: Hack while we don't have PoT-based slot worker, remove once we do
parent_pre_digest
.proof_of_time
.as_ref()
.map(|p| p.proofs().last().slot_number)
.unwrap_or_default()
+ SlotNumber::from(parent_pre_digest.slot)
.checked_sub(SlotNumber::from(pre_digest.slot))
.unwrap_or_default(),
pot_digest,
parent_pre_digest.slot.into(),
parent_pot_digest,
maybe_parent_pot_digest,
)
.map_err(PotVerifyError::PotVerifyBlockProofsError)?;

Expand Down
52 changes: 18 additions & 34 deletions crates/sc-consensus-subspace/src/slot_worker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,6 @@ use sp_consensus_subspace::digests::{extract_pre_digest, CompatibleDigestItem, P
use sp_consensus_subspace::{FarmerPublicKey, FarmerSignature, SignedVote, SubspaceApi, Vote};
use sp_core::crypto::ByteArray;
use sp_core::H256;
#[cfg(feature = "pot")]
use sp_runtime::traits::NumberFor as BlockNumberFor;
use sp_runtime::traits::{Block as BlockT, Header, One, Saturating, Zero};
use sp_runtime::DigestItem;
use std::future::Future;
Expand All @@ -66,15 +64,7 @@ use subspace_verification::{
/// Errors while building the block proof of time.
#[cfg(feature = "pot")]
#[derive(Debug, thiserror::Error)]
pub enum PotCreateError<Block: BlockT> {
/// Parent block has no proof of time digest.
#[error("Parent block missing proof of time : {parent_block_number}/{parent_slot_number}/{slot_number}")]
ParentMissingPotDigest {
parent_block_number: BlockNumberFor<Block>,
parent_slot_number: SlotNumber,
slot_number: SlotNumber,
},

pub enum PotCreateError {
/// Proof creation failed.
#[error("Proof of time error: {0}")]
PotGetBlockProofsError(#[from] PotGetBlockProofsError),
Expand Down Expand Up @@ -231,10 +221,6 @@ where
let parent_hash = parent_header.hash();
let runtime_api = self.client.runtime_api();

#[cfg(not(feature = "pot"))]
let global_randomness =
extract_global_randomness_for_block(self.client.as_ref(), parent_hash).ok()?;

// If proof of time is enabled, collect the proofs that go into this
// block and derive randomness from the last proof.
#[cfg(feature = "pot")]
Expand All @@ -245,7 +231,15 @@ where
proof_of_time.as_ref(),
parent_header,
&parent_pre_digest,
slot.into(),
// TODO: Hack while we don't have PoT-based slot worker, remove once we do
parent_pre_digest
.proof_of_time
.as_ref()
.map(|p| p.proofs().last().slot_number)
.unwrap_or_default()
+ SlotNumber::from(parent_slot)
.checked_sub(SlotNumber::from(slot))
.unwrap_or_default(),
)
.await
.ok()?;
Expand All @@ -258,6 +252,12 @@ where
)
};

// TODO: There is some kind of mess with PoT randomness right now that doesn't make a
// lot of sense, restore this check once that is resolved
// #[cfg(not(feature = "pot"))]
let global_randomness =
extract_global_randomness_for_block(self.client.as_ref(), parent_hash).ok()?;

let (solution_range, voting_solution_range) =
extract_solution_ranges_for_block(self.client.as_ref(), parent_hash).ok()?;

Expand Down Expand Up @@ -624,30 +624,14 @@ where
parent_header: &Block::Header,
parent_pre_digest: &PreDigest<FarmerPublicKey, FarmerPublicKey>,
slot_number: SlotNumber,
) -> Result<PotPreDigest, PotCreateError<Block>> {
) -> Result<PotPreDigest, PotCreateError> {
let block_number = *parent_header.number() + One::one();

// Block 1 does not have proofs
if block_number.is_one() {
return Ok(PotPreDigest::FirstBlock(slot_number));
}

// Block 2 onwards.
// Get the start slot number for the proofs in the new block.
let parent_pot_digest = parent_pre_digest.proof_of_time.as_ref().ok_or_else(|| {
// PoT needs to be present in the block if feature is enabled.
PotCreateError::ParentMissingPotDigest {
parent_block_number: *parent_header.number(),
parent_slot_number: parent_pre_digest.slot.into(),
slot_number,
}
})?;

proof_of_time
.get_block_proofs(
block_number.into(),
slot_number,
parent_pot_digest,
&parent_pre_digest.proof_of_time,
Some(self.subspace_link.slot_duration().as_duration()),
)
.await
Expand Down
8 changes: 7 additions & 1 deletion crates/sc-proof-of-time/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ pub use time_keeper::TimeKeeper;
#[derive(Debug, Clone)]
pub struct PotConfig {
/// PoT key used initially when PoT chain starts.
// TODO: Use this field
// TODO: Also add seed field here
pub initial_key: PotKey,

/// Frequency of entropy injection from consensus.
Expand Down Expand Up @@ -52,6 +52,10 @@ pub struct PotConfig {
/// Components initialized during the new_partial() phase of set up.
#[derive(Debug)]
pub struct PotComponents {
/// PoT key used initially when PoT chain starts.
// TODO: Remove this from here, shouldn't be necessary eventually
pub(crate) initial_key: PotKey,

/// If the role is time keeper or node client.
is_time_keeper: bool,

Expand All @@ -71,9 +75,11 @@ impl PotComponents {
let proof_of_time = ProofOfTime::new(config.pot_iterations, config.num_checkpoints)
// TODO: Proper error handling or proof
.expect("Failed to initialize proof of time");
let initial_key = config.initial_key;
let (protocol_state, consensus_state) = init_pot_state(config, proof_of_time);

Self {
initial_key,
is_time_keeper,
proof_of_time,
protocol_state,
Expand Down
Loading

0 comments on commit 0ac040d

Please sign in to comment.