Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added RevertibleStorage to handle storage that does not need to be verified using Merkle Tries #27

Closed
wants to merge 3 commits into from

Conversation

Trantorian1
Copy link
Contributor

Pull Request type

  • Feature

What is the current behavior?

Bonsai lib currently only handles verifiable, consensus-critical storage, with each new commit resulting in recursive hashing to compute a root hash. This can be a problem since not all data stored in Madara or Deoxys is essential to the state of the chain. This is for example the case for contract classes, where only the contract class hash is used to compute the state root for a given block.

Currently, storage that is not consensus-critical is still handled using Substrate storage, but this is also overkill since runtime storage in Substrate also uses Merkle trees for state verification. This is not recommended for large storage, as is currently the case.

"reading and writing data to storage is expensive. In addition, storing unnecessarily large data sets can slow your network and strain system resources."
source: Substrate doc

A solution to this is to implement simple key-value based revertible storage using the abstractions already provided by the Bonsai lib. This would allow for the easy storage of data that is not consensus critical yet still needs to be reverted to a previous state in the chain in case of a reorg or rpc call on a previous block.

On the long run, this could allow us to migrate away from Substrate as a whole towards our own custom storage solutions.

What is the new behavior?

This pr introduces a new type of storage, RevertibleStorage, which functions similarly to BonsaiStorage but which does not use Merkle tries to compute the state of the storage. This means it is not possible to compute the storage state for RevertibleStorage. This results in simpler, smaller storage for data that is not consensus-critical.

Does this introduce a breaking change?

No. While RevertibleStorage functions similarly to BonsaiStorage, it exists completely apart from it and does not otherwise change it's inner workings.

Other information

As much as possible, RevertibleStorage has the same behavior as BonsaiStorage. I wonder though if it is still pertinent to retain identifiers for storage access for the sake of feature parity. Let me know your thoughts on that.

src/key_value_db.rs Show resolved Hide resolved
&mut self,
requested_id: ChangeID,
) -> Result<(), BonsaiStorageError<DB::DatabaseError>> {
let kv = &mut self.db;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to make a function with this code and the one from revert_to (that is not tied to any of the storage) and call it here instead of duplicating the code ?

Copy link
Contributor Author

@Trantorian1 Trantorian1 Apr 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm generally a bit on the fence when it comes to refactoring small bits of code like this, as I tend to prefer having functions explicitly state their inner workings. In this case, I'm not sure having a single code source for revert_to between RevertibleStorage and BonsaiStorage is a good idea, especially since these two structs each have their own unique approach to storage. I think it might be a better to keep them separate for now, as the logic isn't much complicated.

src/lib.rs Outdated Show resolved Hide resolved
ChangeID: id::Id,
{
db: KeyValueDB<DB, ChangeID>,
cache_storage_modified: HashMap<TrieKey, InsertOrRemove<Vec<u8>>>,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need any temporary storage in this structure KeyValueDB already do it for you and provide the features to store changes etc. You should called its insert remove etc in your function and just call commit on it in the commit

Copy link
Contributor Author

@Trantorian1 Trantorian1 Apr 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't KeyValue also write to the db during insertion if a batch isn't provided? See here.

@antiyro
Copy link
Member

antiyro commented Apr 24, 2024

Closing this as it is not relevent anymore according to the upcoming optimizations

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants