Open tmpolaczyk opened 7 months ago
Calling
GenesisConfigBuilderRuntimeCaller::new()
always creates a new executor. This seems to ignore the wasm cache, and in the end this causes the wasm runtime to be compiled twice.
I'll look into this, I'd expect that cache is re-used. Otherwise your proposal sounds right at first glance.
Thanks, you can reproduce it by adding a log here: https://github.com/paritytech/polkadot-sdk/blob/f2645eec12f080a66228aedbeaecea2c913570ed/substrate/client/executor/src/wasm_runtime.rs#L250
I was able to see two calls with the same code_hash
.
It seems that implementing your proposal is not that easy (or elegant) due to how involved parties are disjointed.
The storage is built by using BuildStorage::build_storage
method from dyn ChainSpec
object which is kept in config
and converted to BuildStorage
by ChainSpec::as_storage_builder
.
ChainSpec instance within config
is created before the executor is instantiated (kinda chicken and egg problem).
Both BuildStorage
and ChainSpec
do not provide a mean to inject Executor
. We could do this, e.g. by extending ChainSpec
trait with set_executor
method, but - at the moment - I am not sure if this is right (feels like this method does not really belong there).
The other solution to this problem, which seems more appropriate for me, could be runtime-cache shared (kinda static instance) across multiply instances of Executor
instead of per executor cache.
@koute do you think shared-cache makes sense, and is doable? (cc: @bkchr)
The other solution to this problem, which seems more appropriate for me, could be runtime-cache shared (kinda static instance) across multiply instances of
Executor
instead of
We had this and we don't want to go back there.
We need to solve this here. There could be for example an extra method to GenesisBuilder
with_chain_spec
or whatever that doesn't take BuildStorage
and then pass the executor when building the storage.
I spent some time on this. ChainSpec
is available as trait object (dyn ChainSpec
), what effectively prevents from easy trait extension with generic executor-related methods. I did some work with callback allowing injection of executor here: https://github.com/paritytech/polkadot-sdk/compare/master...mku-chainspec-avoid-double-compilation (which is working) but I am not really happy with this. Another (proper) solution would require some heavier refactor around how Configuration
, Executor
and ChainSpec
are created.
@tmpolaczyk another idea: maybe you could use raw chainspec in your tests to avoid double compilation if that is a huge pain?
maybe you could use raw chainspec in your tests to avoid double compilation if that is a huge pain?
I did not think about that, but we use --dev
, it is going to be weird to change it to --chain dancebox_dev_raw.json
...
Anyway this is not urgent, I managed to improve our test time by using #1641, so now instead of compiling the wasm twice we only compile it once (because of this bug, after it is fixed we are going to use the precompiled wasm only). I liked your idea about a global instance cache, I may implement it in our fork if this doesn't get fixed.
But I agree that a proper solution would be to change the api here, this way as a parachain we don't need any strange hacks and everything works as expected. Not sure how to do it though.
Is there an existing issue?
Experiencing problems? Have you tried our Stack Exchange first?
Motivation
After upgrading to polkadot 1.6.0 in tanssi (https://github.com/moondance-labs/tanssi/commit/c427348caf30095f50be529fc6a9aedbc540a08f), we noticed that typescript
dev_tests
take twice as long now. These tests runtanssi-node --dev
for each test, so the issue was that starting a new node was taking longer than before. The cause seems to be the wasm compilation, which takes a considerable amount of time.After some debugging, it looks like the runtime wasm is being compiled 3 times. One of the redundant ones is fixed by #3447, and the other is this one.
Calling
GenesisConfigBuilderRuntimeCaller::new()
always creates a new executor. This seems to ignore the wasm cache, and in the end this causes the wasm runtime to be compiled twice.Request
Add a method like
GenesisConfigBuilderRuntimeCaller::with_executor
or similar, to allow the user to pass an executor. Use that method inGenesisBlockBuilder::new()
, which already has access to the user executor.GenesisConfigBuilderRuntimeCaller
should use that executor instead of creating a new one.Maybe relevant: #2188
Solution
No response
Are you willing to help with this request?
Yes!