Network round trip between EVM Executor machinery and StateDB component is a known factor of slowness for each EVM execution.
By having a memory cache of account’s balance, nonce and maybe code (full or LRU cache), we eliminate a common overhead of every single call that will ever be made. Optimizing the speed of those information is crucial for a fast execution of calls.
In that optic, I’m thinking about two different approaches (and variations of those). One of the challenge with the cache in EVM Executor is we need to actually cache “range” of data and not “instant” value. For example, a naive LRU cache where the key would be defined by account + block number, there is good chance that this cache will not be read as often as you might think, specially for use cases where repeatedly polling of the live value happens for each and every block.
We must cache the knowledge that the value was set to this value between block X and block Y. The key space in StateDB right now is mostly like this (FluxDB format):
- Account’s Balance:
00 A000 <address (20 bytes)> <blockHeight (u64 8 bytes LE)> <value Proto<BalanceValue>>
- Account’s Code:
00 A001 <address (20 bytes)> <blockHeight (u64 8 bytes LE)> <value Proto<CodeValue>>
- Account’s Nonce:
00 A001 <address (20 bytes)> <blockHeight (u64 8 bytes LE)> <value Proto<NonceValue>> Proto>`
### Database “dump” to memory + live syncing
### Database “dump” of active state + live syncing
### LRU with “row” dump to memory
TBC
Network round trip between EVM Executor machinery and StateDB component is a known factor of slowness for each EVM execution.
By having a memory cache of account’s balance, nonce and maybe code (full or LRU cache), we eliminate a common overhead of every single call that will ever be made. Optimizing the speed of those information is crucial for a fast execution of calls.
In that optic, I’m thinking about two different approaches (and variations of those). One of the challenge with the cache in EVM Executor is we need to actually cache “range” of data and not “instant” value. For example, a naive LRU cache where the key would be defined by account + block number, there is good chance that this cache will not be read as often as you might think, specially for use cases where repeatedly polling of the live value happens for each and every block.
We must cache the knowledge that the value was set to this value between block X and block Y. The key space in StateDB right now is mostly like this (FluxDB format):
00 A000 <address (20 bytes)> <blockHeight (u64 8 bytes LE)> <value Proto<BalanceValue>>00 A001 <address (20 bytes)> <blockHeight (u64 8 bytes LE)> <value Proto<CodeValue>>00 A001 <address (20 bytes)> <blockHeight (u64 8 bytes LE)> <value Proto<NonceValue>>Proto>`