This repository has been archived by the owner on Nov 15, 2023. It is now read-only.
Implement TrieCache
for validate_block
#2432
Labels
I7-refactor
Code needs refactoring.
I9-optimisation
An enhancement to provide better overall performance in terms of time-to-completion for a task.
J0-enhancement
An additional feature request.
When validating a block through
validate_block
the storage proof is loaded in aMemoryDb
. ThisMemoryDb
works as backend for the trie when accessing any data in the state. While implementing theTrieCache
in Substrate the benchmarks have shown that reading theTrie
by going to the backend/database was up to factor 10 slower. In case ofvalidate_block
we don't need to go to disc, as we have everything in memory. However, the experiments also showed that the constant decoding of trie nodes is also degrading the performance. So, we should implement support for using theTrieCache
as well invalidate_block
. This will require some internal changes to Substrate to make theTrieCache
insp-state-machine
generic. This didn't worked when implementing theTrieCache
in Substrate, but now with GATs being available in Rust stable we can change Substrate to have a genericTrieCache
. We should also provide our own implementation of theTrieCache
trait in Cumulus that can be much simpler than the one we have in Substrate. We don't need any kind of ensuring that the data is not overflowing the memory, because we already have all data in memory and we can probably simplify a lot of other things.As a perquisite we should implement the following benchmark: #2048
This should theoretically show some performance improvements after this issue is tackled and it would be nice to show this through this benchmark.
This should not only improve the performance of
validate_block
, but also should lead to an improved memory usage. If we look at the current situation. We have the storage proof stored in theMemoryDb
and we need to decode every trie node every time we access it. This decoding requires memory allocations and memory copying and at the end we also copy the actual value to return it. With theTrieCache
we will decode the nodes only once and every other access to the trie node should go through the cache. This means that we can implement aOneTimeReadBackend
that removes the data from its internal store on the first read, because the cache should afterwards serve these requests. To be fully "memory optimized" this will require certain other changes in the trie crate to not returnVec<u8>
and instead returntrie::Bytes
to prevent that we need to clone values when returning them from the trie, but this is some further optimization.The text was updated successfully, but these errors were encountered: