Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Commit

Permalink
Pick some runtime cleanup from Prototype 2.2
Browse files Browse the repository at this point in the history
  • Loading branch information
davxy committed Sep 24, 2022
1 parent ac2fc9c commit 8f43727
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 122 deletions.
6 changes: 3 additions & 3 deletions bin/node-sassafras/node/src/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ pub fn new_full(mut config: Configuration) -> Result<TaskManager, ServiceError>

let slot_duration = sassafras_link.genesis_config().slot_duration();

let sassafras_config = sc_consensus_sassafras::SassafrasParams {
let sassafras_params = sc_consensus_sassafras::SassafrasParams {
client: client.clone(),
keystore: keystore_container.sync_keystore(),
select_chain,
Expand All @@ -274,7 +274,7 @@ pub fn new_full(mut config: Configuration) -> Result<TaskManager, ServiceError>
sync_oracle: network.clone(),
justification_sync_link: network.clone(),
force_authoring,
create_inherent_data_providers: move |_, ()| async move {
create_inherent_data_providers: move |_, _| async move {
let timestamp = sp_timestamp::InherentDataProvider::from_system_time();

let slot =
Expand All @@ -286,7 +286,7 @@ pub fn new_full(mut config: Configuration) -> Result<TaskManager, ServiceError>
},
};

let sassafras = sc_consensus_sassafras::start_sassafras(sassafras_config)?;
let sassafras = sc_consensus_sassafras::start_sassafras(sassafras_params)?;

// the Sassafras authoring task is considered essential, i.e. if it
// fails we take down the service with it.
Expand Down
147 changes: 56 additions & 91 deletions bin/node-sassafras/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,21 +41,55 @@ pub type BlockNumber = u32;
/// Alias to 512-bit hash when used in the context of a transaction signature on the chain.
pub type Signature = MultiSignature;

/// Index of a transaction in the chain.
pub type Index = u32;

/// A hash of some data used by the chain.
pub type Hash = sp_core::H256;

/// Block header type as expected by this runtime.
pub type Header = generic::Header<BlockNumber, BlakeTwo256>;

/// The SignedExtension to the basic transaction logic.
pub type SignedExtra = (
frame_system::CheckNonZeroSender<Runtime>,
frame_system::CheckSpecVersion<Runtime>,
frame_system::CheckTxVersion<Runtime>,
frame_system::CheckGenesis<Runtime>,
frame_system::CheckEra<Runtime>,
frame_system::CheckNonce<Runtime>,
frame_system::CheckWeight<Runtime>,
pallet_transaction_payment::ChargeTransactionPayment<Runtime>,
);

/// Unchecked extrinsic type as expected by this runtime.
pub type UncheckedExtrinsic =
generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, SignedExtra>;

/// Block type as expected by this runtime.
pub type Block = generic::Block<Header, UncheckedExtrinsic>;

/// Some way of identifying an account on the chain. We intentionally make it equivalent
/// to the public key of our transaction signing scheme.
pub type AccountId = <<Signature as Verify>::Signer as IdentifyAccount>::AccountId;

/// The address format for describing accounts.
pub type Address = sp_runtime::MultiAddress<AccountId, ()>;

/// Balance of an account.
pub type Balance = u128;

/// Index of a transaction in the chain.
pub type Index = u32;

/// A hash of some data used by the chain.
pub type Hash = sp_core::H256;
/// The payload being signed in transactions.
pub type SignedPayload = generic::SignedPayload<RuntimeCall, SignedExtra>;

/// Type used for expressing timestamp.
pub type Moment = u64;
/// Executive: handles dispatch to the various modules.
pub type Executive = frame_executive::Executive<
Runtime,
Block,
frame_system::ChainContext<Runtime>,
Runtime,
AllPalletsWithSystem,
>;

/// Opaque types. These are used by the CLI to instantiate machinery that don't need to know
/// the specifics of the runtime. They can then be made to be agnostic over specific formats
Expand All @@ -65,7 +99,6 @@ pub mod opaque {
use super::*;

pub use sp_runtime::OpaqueExtrinsic as UncheckedExtrinsic;

/// Opaque block header type.
pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
/// Opaque block type.
Expand All @@ -81,51 +114,25 @@ impl_opaque_keys! {
}
}

// To learn more about runtime versioning and what each of the following value means:
// https://docs.substrate.io/v3/runtime/upgrades#runtime-versioning
#[sp_version::runtime_version]
pub const VERSION: RuntimeVersion = RuntimeVersion {
spec_name: create_runtime_str!("node-sassafras"),
impl_name: create_runtime_str!("node-sassafras"),
authoring_version: 1,
// The version of the runtime specification. A full node will not attempt to use its native
// runtime in substitute for the on-chain Wasm runtime unless all of `spec_name`,
// `spec_version`, and `authoring_version` are the same between Wasm and native.
// This value is set to 100 to notify Polkadot-JS App (https://polkadot.js.org/apps) to use
// the compatible custom types.
spec_version: 100,
impl_version: 1,
apis: RUNTIME_API_VERSIONS,
transaction_version: 1,
state_version: 1,
};

/// This determines the average expected block time that we are targeting.
/// Blocks will be produced at a minimum duration defined by `SLOT_DURATION`.
/// `SLOT_DURATION` is picked up by `pallet_timestamp` which is in turn picked
/// up by `pallet_sassafras` to implement `fn slot_duration()`.
///
/// Change this to adjust the block time.
pub const MILLISECS_PER_BLOCK: u64 = 6000;

// NOTE: Currently it is not possible to change the slot duration after the chain has started.
// Attempting to do so will brick block production.
pub const SLOT_DURATION: u64 = MILLISECS_PER_BLOCK;
/// Sassafras slot duration in milliseconds
pub const SLOT_DURATION_IN_MILLISECONDS: u64 = 3000;

// TODO-SASS-P4: this is an intentional small value used for testing
pub const EPOCH_DURATION_IN_BLOCKS: BlockNumber = 10;

pub const EPOCH_DURATION_IN_SLOTS: u64 = {
const SLOT_FILL_RATE: f64 = MILLISECS_PER_BLOCK as f64 / SLOT_DURATION as f64;

(EPOCH_DURATION_IN_BLOCKS as f64 * SLOT_FILL_RATE) as u64
};

// Time is measured by number of blocks.
pub const MINUTES: BlockNumber = 60_000 / (MILLISECS_PER_BLOCK as BlockNumber);
pub const HOURS: BlockNumber = MINUTES * 60;
pub const DAYS: BlockNumber = HOURS * 24;
/// Sassafras epoch duration in slots.
pub const EPOCH_DURATION_IN_SLOTS: u64 = 10;

/// Max authorities for both Sassafras and Grandpa.
pub const MAX_AUTHORITIES: u32 = 32;

/// The version information used to identify this runtime when compiled natively.
Expand All @@ -134,8 +141,8 @@ pub fn native_version() -> NativeVersion {
NativeVersion { runtime_version: VERSION, can_author_with: Default::default() }
}

const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75);

// Required to send unsigned transactoins from Sassafras pallet
// TODO-SASS-P2 double check (isn't grandpa requiring the same thing???
impl<C> frame_system::offchain::SendTransactionTypes<C> for Runtime
where
RuntimeCall: From<C>,
Expand All @@ -144,6 +151,8 @@ where
type OverarchingCall = RuntimeCall;
}

const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75);

parameter_types! {
pub const BlockHashCount: BlockNumber = 2400;
pub const Version: RuntimeVersion = VERSION;
Expand Down Expand Up @@ -184,14 +193,9 @@ impl frame_system::Config for Runtime {
type MaxConsumers = frame_support::traits::ConstU32<16>;
}

parameter_types! {
pub const EpochDuration: u64 = EPOCH_DURATION_IN_SLOTS;
pub const ExpectedBlockTime: Moment = MILLISECS_PER_BLOCK;
}

impl pallet_sassafras::Config for Runtime {
type EpochDuration = EpochDuration;
type ExpectedBlockTime = ExpectedBlockTime;
type SlotDuration = ConstU64<SLOT_DURATION_IN_MILLISECONDS>;
type EpochDuration = ConstU64<EPOCH_DURATION_IN_SLOTS>;
#[cfg(feature = "use-session-pallet")]
type EpochChangeTrigger = pallet_sassafras::ExternalTrigger;
#[cfg(not(feature = "use-session-pallet"))]
Expand All @@ -217,7 +221,7 @@ impl pallet_grandpa::Config for Runtime {
impl pallet_timestamp::Config for Runtime {
type Moment = u64;
type OnTimestampSet = ();
type MinimumPeriod = ConstU64<{ SLOT_DURATION / 2 }>;
type MinimumPeriod = ConstU64<{ SLOT_DURATION_IN_MILLISECONDS / 2 }>;
type WeightInfo = ();
}

Expand Down Expand Up @@ -297,43 +301,6 @@ construct_runtime!(
}
);

/// The address format for describing accounts.
pub type Address = sp_runtime::MultiAddress<AccountId, ()>;

/// Block header type as expected by this runtime.
pub type Header = generic::Header<BlockNumber, BlakeTwo256>;

/// Block type as expected by this runtime.
pub type Block = generic::Block<Header, UncheckedExtrinsic>;

/// The SignedExtension to the basic transaction logic.
pub type SignedExtra = (
frame_system::CheckNonZeroSender<Runtime>,
frame_system::CheckSpecVersion<Runtime>,
frame_system::CheckTxVersion<Runtime>,
frame_system::CheckGenesis<Runtime>,
frame_system::CheckEra<Runtime>,
frame_system::CheckNonce<Runtime>,
frame_system::CheckWeight<Runtime>,
pallet_transaction_payment::ChargeTransactionPayment<Runtime>,
);

/// Unchecked extrinsic type as expected by this runtime.
pub type UncheckedExtrinsic =
generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, SignedExtra>;

/// The payload being signed in transactions.
pub type SignedPayload = generic::SignedPayload<RuntimeCall, SignedExtra>;

/// Executive: handles dispatch to the various modules.
pub type Executive = frame_executive::Executive<
Runtime,
Block,
frame_system::ChainContext<Runtime>,
Runtime,
AllPalletsWithSystem,
>;

#[cfg(feature = "runtime-benchmarks")]
#[macro_use]
extern crate frame_benchmarking;
Expand Down Expand Up @@ -411,8 +378,8 @@ impl_runtime_apis! {
impl sp_consensus_sassafras::SassafrasApi<Block> for Runtime {
fn configuration() -> sp_consensus_sassafras::SassafrasConfiguration {
sp_consensus_sassafras::SassafrasConfiguration {
slot_duration: Sassafras::slot_duration(),
epoch_duration: EpochDuration::get(),
slot_duration: SLOT_DURATION_IN_MILLISECONDS,
epoch_duration: EPOCH_DURATION_IN_SLOTS,
authorities: Sassafras::authorities().to_vec(),
randomness: Sassafras::randomness(),
threshold_params: Sassafras::config(),
Expand All @@ -435,9 +402,7 @@ impl_runtime_apis! {
SessionKeys::generate(seed)
}

fn decode_session_keys(
encoded: Vec<u8>,
) -> Option<Vec<(Vec<u8>, KeyTypeId)>> {
fn decode_session_keys(encoded: Vec<u8>) -> Option<Vec<(Vec<u8>, KeyTypeId)>> {
SessionKeys::decode_into_raw_public_keys(&encoded)
}
}
Expand Down
61 changes: 34 additions & 27 deletions frame/sassafras/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,21 +98,14 @@ pub mod pallet {

/// Configuration parameters.
#[pallet::config]
#[pallet::disable_frame_system_supertrait_check]
pub trait Config: pallet_timestamp::Config + SendTransactionTypes<Call<Self>> {
/// The amount of time, in slots, that each epoch should last.
/// NOTE: Currently it is not possible to change the epoch duration after the chain has
/// started. Attempting to do so will brick block production.
pub trait Config: frame_system::Config + SendTransactionTypes<Call<Self>> {
/// The amount of time, in milliseconds, that each slot should last.
#[pallet::constant]
type EpochDuration: Get<u64>;
type SlotDuration: Get<u64>;

/// The expected average block time at which Sassafras should be creating
/// blocks. Since Sassafras is probabilistic it is not trivial to figure out
/// what the expected average block time should be based on the slot
/// duration and the security parameter `c` (where `1 - c` represents
/// the probability of a slot being empty).
/// The amount of time, in slots, that each epoch should last.
#[pallet::constant]
type ExpectedBlockTime: Get<Self::Moment>;
type EpochDuration: Get<u64>;

/// Sassafras requires some logic to be triggered on every block to query for whether an
/// epoch has ended and to perform the transition to the next epoch.
Expand All @@ -130,13 +123,11 @@ pub mod pallet {
type MaxTickets: Get<u32>;
}

// TODO-SASS-P2
/// Sassafras runtime errors.
#[pallet::error]
pub enum Error<T> {
/// Submitted configuration is invalid.
InvalidConfiguration,
// TODO-SASS P2 ...
}

/// Current epoch index.
Expand Down Expand Up @@ -302,6 +293,7 @@ pub mod pallet {
#[pallet::call]
impl<T: Config> Pallet<T> {
/// Submit next epoch tickets.
///
/// TODO-SASS-P3: this is an unsigned extrinsic. Can we remov ethe weight?
#[pallet::weight(10_000)]
pub fn submit_tickets(
Expand All @@ -321,16 +313,22 @@ pub mod pallet {
Ok(())
}

/// Plan an epoch config change. The epoch config change is recorded and will be enacted on
/// the next call to `enact_session_change`. The config will be activated one epoch after.
/// Multiple calls to this method will replace any existing planned config change that had
/// not been enacted yet.
/// Plan an epoch config change.
///
/// The epoch config change is recorded and will be enacted on the next call to
/// `enact_session_change`.
///
/// The config will be activated one epoch after. Multiple calls to this method will
/// replace any existing planned config change that had not been enacted yet.
///
/// TODO: TODO-SASS-P4: proper weight
#[pallet::weight(10_000)]
pub fn plan_config_change(
origin: OriginFor<T>,
config: SassafrasEpochConfiguration,
) -> DispatchResult {
ensure_root(origin)?;

ensure!(
config.redundancy_factor != 0 && config.attempts_number != 0,
Error::<T>::InvalidConfiguration
Expand Down Expand Up @@ -425,13 +423,13 @@ pub mod pallet {

// Inherent methods
impl<T: Config> Pallet<T> {
/// Determine the Sassafras slot duration based on the Timestamp module configuration.
pub fn slot_duration() -> T::Moment {
// TODO-SASS-P2: clarify why this is doubled (copied verbatim from BABE)
// We double the minimum block-period so each author can always propose within
// the majority of their slot.
<T as pallet_timestamp::Config>::MinimumPeriod::get().saturating_mul(2u32.into())
}
// // TODO-SASS-P2: I don't think this is really required
// /// Determine the Sassafras slot duration based on the Timestamp module configuration.
// pub fn slot_duration() -> T::Moment {
// // We double the minimum block-period so each author can always propose within
// // the majority of their slot.
// <T as pallet_timestamp::Config>::MinimumPeriod::get().saturating_mul(2u32.into())
// }

/// Determine whether an epoch change should take place at this block.
/// Assumes that initialization has already taken place.
Expand Down Expand Up @@ -728,17 +726,26 @@ impl<T: Config> Pallet<T> {
metadata.segments_count = segments_count;
}

/// Submit next epoch validator tickets via an unsigned extrinsic.
/// Submit next epoch validator tickets via an unsigned extrinsic constructed with a call to
/// `submit_unsigned_transaction`.
///
/// The submitted tickets are added to the `NextTickets` list as long as the extrinsic has
/// is called within the first half of the epoch. That is, tickets received within the
/// second half are dropped.
///
/// TODO-SASS-P3: we have to add the zk validity proofs
pub fn submit_tickets_unsigned_extrinsic(mut tickets: Vec<Ticket>) -> bool {
log::debug!(target: "sassafras", "🌳 @@@@@@@@@@ submitting {} tickets", tickets.len());
tickets.sort_unstable();
let tickets = BoundedVec::truncate_from(tickets);
let call = Call::submit_tickets { tickets };
SubmitTransaction::<T, Call<T>>::submit_unsigned_transaction(call.into()).is_ok()
match SubmitTransaction::<T, Call<T>>::submit_unsigned_transaction(call.into()) {
Ok(_) => true,
Err(e) => {
log::error!(target: "runtime::sassafras", "Error submitting tickets {:?}", e);
false
},
}
}
}

Expand Down
Loading

0 comments on commit 8f43727

Please sign in to comment.