fuel-core
fuel-core copied to clipboard
Moved `StorageTransaction` to the `fuel-core-storage` crate
Closes https://github.com/FuelLabs/fuel-core/issues/1589
Overview
The change moves the database transaction logic from the fuel-core
to the fuel-core-storage
level. The corresponding issue described the reason behind it.
Technical details of implementation
The change splits the KeyValueStore
into KeyValueInspect
and KeyValueMutate
, as well the Blueprint
into BlueprintInspect
and BlueprintMutate
. It allows requiring less restricted constraints for any read-related operations.
One of the main ideas of the change is to allow for the actual storage only to implement KeyValueInspect
and Modifiable
without the KeyValueMutate
. It simplifies work with the databases and provides a safe way of interacting with them (Modification into the database can only go through the Modifiable::commit_changes
). This feature is used to track the height of each database during commits and even limit how commits are done, providing additional safety. This part of the change was done as a separate commit.
The StorageTransaction
is a StructuredStorage
that uses StorageTransactionInner
inside to accumulate modifications. Only StorageStorageInner
has a real implementation of the KeyValueMutate
(Other types only implement it in tests).
The implementation of the Modifiable
for the Database
contains a business logic that provides additional safety but limits the usage of the database. The Database
now tracks its height and is responsible for its updates. In the commit_changes
function, it analyzes the changes that were done and tries to find a new height(For example, in the case of the OnChain
database, we are looking for a new Block
in the FuelBlocks
table).
As was planned in the issue, now the executor has full control over how commits to the storage are done.
All mutation methods now require &mut self
- exclusive ownership over the object to be able to write into it. It almost negates the chance of concurrent modification of the storage, but it is still possible since the Database
implements the Clone
trait. To be sure that we don't corrupt the state of the database, the commit_changes
function implements additional safety checks to be sure that we commit updates per each height only once time.
Side changes:
- The
drop
function was moved fromDatabase
toRocksDB
as a preparation for the state rewind since the read view should also keep the drop function until it is destroyed. - The
StatisticTable
table lives in the off-chain worker. - Removed duplication of the
Database
from thedapp::ConcreteStorage
since it is already available from the VM. - The executor return only produced
Changes
instead of the storage transaction, which simplifies the interaction between modules and port definition. - The logic related to the iteration over the storage is moved to the
fuel-core-storage
crate and is now reusable. It provides aninterator
method that duplicates the logic fromMemoryStore
on iterating over theBTreeMap
and methods likeiter_all
,iter_all_by_prefix
, etc. It was done in a separate revivable commit. - The
MemoryTransactionView
is fully replaced by theStorageTransactionInner
. - Removed
flush
method from theDatabase
since it is not needed after https://github.com/FuelLabs/fuel-core/pull/1664 .