paritytech/polkadot-sdk

Make block time configurable

Opened this issue · 17 comments

Enable a developer to start a node (polkadot/polkadot-parachain) with a custom block time.
The configuration could be set by

  • environment variables
  • chain spec config
  • JSON config
  • other

Note: The idea is to not instruct the developer to go and customize runtime code.

Why this is needed?

Today, one of the greatest pain points in the multi-chain JS developer experience is the sluggishness of transactions.
If we were able to configure shorter block times for development in the Polkadot and Cumulus runtimes, this would have a huge positive impact on the DX. This would enable faster app development, testing of more complex scenarios, and smoother contributor onboarding.

xlc commented

you should use chopsticks

Moved to backlog as this is already possible, not particularly easy though

bkchr commented

@juangirini please don't post internal links. People outside of parity can not access them.

@juangirini @kianenigma Would it be possible to re-prioritize this issue?

This has a huge impact in the DX for JS developers and to onboard new contributors.
The idea is to not ask a JS dev to do Rust code to customize a node.
Ideally, it should be some configuration in the genesis.

bkchr commented

This can not just be done at genesis. It requires that you build with the fast-runtime feature in Polkadot for example. There could be for example prepared chain specs which provide a fast-runtime enabled runtime.

Sorry, I didn't want suggest what is the best way to implement this.

But I do wanted to highlight the huge impact on the DX.
For JS DApp developers, this would enable faster app development, testing of more complex scenarios, and smoother contributor onboarding.

Regarding fast-runtime, to my knowledge this is only available in polkadot, it would be nice if it can be set to update MILLISECS_PER_BLOCK to the minimun.
It would also be nice to add the same feature to polkadot-parachain and enable a better DX for multi-chain JS DApp developers.

xlc commented

I can’t believe you still haven’t tried https://github.com/AcalaNetwork/chopsticks

bkchr commented

I can’t believe you still haven’t tried https://github.com/AcalaNetwork/chopsticks

What @xlc is saying 🙈

@xlc apologies for the late reply and thx for the chopsticks suggestion.

I did try chopsticks and it's a super nice tool.

However, the idea for this request is to have some kind of native support within polkadot and polkadot-parachain so it doesn't require a simulation layer (like the one provided by chopsticks).

xlc commented

why? you can’t request something without explanation

xlc commented

But I do wanted to highlight the huge impact on the DX.
For JS DApp developers, this would enable faster app development, testing of more complex scenarios, and smoother contributor onboarding.

this is already covered by chopsticks so it doesn’t count

I think it depends

  • there may be scenarios where the dependency risk of using another tool that simulates parts of the RPC node (like chopsticks) on top of polkadot is fine
  • and, there may be scenarios where a production like node with a faster block time is preferred
xlc commented

there may be scenarios where the dependency risk of using another tool that simulates parts of the RPC node (like chopsticks) on top of polkadot is fine

I just don't understand this sentence. Can you elaborate?

and, there may be scenarios where a production like node with a faster block time is preferred

I guess you really didn't try Chopsticks. Please, give it a go. It produces block as soon as transaction is received OR you can be manually triggered by dev_newBlock RPC.

@xlc I am aware about chopsticks instant transactions and (again) I have tried Chopsticks.

Regarding dependency risk, there may be scenarios where it’s fine to add an extra dependency to the workflow and be at the mercy of the dependency reliability/features/bugs.

And there may be scenarios where you are not wiling to take any extra dependency risks.

For example, exploring chopsticks I spotted AcalaNetwork/chopsticks#304 and AcalaNetwork/chopsticks#305 findings related to the simulated RPC API, some people would be ok taking these risks.

On the other side, there may be people that prefer a workflow without any simulated RPC API and trade instant transactions with a faster block time using a production like node.

Would it help if we make a new node-template that has fast block times? but still, if you want that on Polkadot, you need to change a few lines of code in there.

All of that is if you really really have to use a full, real node. You should consider using Chopsticks as well.

To change the block time in the node-template, modify this line:

/// 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_aura` to implement `fn slot_duration()`.
///
/// Change this to adjust the block time.
pub const MILLISECS_PER_BLOCK: u64 = 6000;

For example, if I change it to 1000, the node starts producing blocks every second.

node-template-faster-block-time.mov

To change the block time in the kitchensink node (for development purposes), modify this line:

	/// Since BABE is probabilistic this is the average expected block time that
	/// we are targeting. Blocks will be produced at a minimum duration defined
	/// by `SLOT_DURATION`, but some slots will not be allocated to any
	/// authority and hence no block will be produced. We expect to have this
	/// block time on average following the defined slot duration and the value
	/// of `c` configured for BABE (where `1 - c` represents the probability of
	/// a slot being empty).
	/// This value is only used indirectly to define the unit constants below
	/// that are expressed in blocks. The rest of the code should use
	/// `SLOT_DURATION` instead (like the Timestamp pallet for calculating the
	/// minimum period).
	///
	/// If using BABE with secondary slots (default) then all of the slots will
	/// always be assigned, in which case `MILLISECS_PER_BLOCK` and
	/// `SLOT_DURATION` should have the same value.
	///
	/// <https://research.web3.foundation/en/latest/polkadot/block-production/Babe.html#-6.-practical-results>
	pub const MILLISECS_PER_BLOCK: Moment = 3000;

For example, if I change it to 1000, the node starts producing blocks every second.

kitchensink-faster-block-time-01.mov

Keep in mind, the kitchensink runtime uses BABE where as the node-template uses AURA to produce blocks.

Simply changing MILLISECS_PER_BLOCK without understanding the underlying logic that goes into block production, block importing, syncing, and overall block time can result in undesired consequences. While this may be sufficient for testing on a local machine for demo or development purposes, this is not intended for production use. You should have a firm understanding of how the block production mechanism works, how blocks are imported, how they are propagated, how block time is broken up, and how BlockWeights work in order to modify block time in a scalable manner that suits your needs and works in a deployed environment.

Here are some good discussions on these topics: