Implement nested storage transactions (#6269)

* Add transactional storage functionality to OverlayChanges

A collection already has a natural None state. No need to
wrap it with an option.

* Add storage transactions runtime interface

* Add frame support for transactions

* Fix committed typo

* Rename 'changes' variable to 'overlay'

* Fix renaming change

* Fixed strange line break

* Rename clear to clear_where

* Add comment regarding delete value on mutation

* Add comment which changes are covered by a transaction

* Do force the arg to with_transaction return a Result

* Use rust doc comments on every documentable place

* Fix wording of insert_diry doc

* Improve doc on start_transaction

* Rename value to overlayed in close_transaction

* Inline negation

* Improve wording of close_transaction comments

* Get rid of an expect by using get_or_insert_with

* Remove trailing whitespace

* Rename should to expected in tests

* Rolling back a transaction must mark the overlay as dirty

* Protect client initiated storage tx from being droped by runtime

* Review nits

* Return Err when entering or exiting runtime fails

* Documentation fixup

* Remove close type

* Move enter/exit runtime to excute_aux in the state-machine

* Rename Discard -> Rollback

* Move child changeset creation to constructor

* Move child spawning into the closure

* Apply suggestions from code review

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>

* Fixup for code suggestion

* Unify re-exports

* Rename overlay_changes to mod.rs and move into subdir

* Change proof wording

* Adapt a new test from master to storage-tx

* Suggestions from the latest round of review

* Fix warning message

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>
This commit is contained in:
Alexander Theißen
2020-06-23 11:17:53 +02:00
committed by GitHub
parent 6aa8965f33
commit bb2df2122e
16 changed files with 1383 additions and 532 deletions
@@ -29,6 +29,33 @@ pub mod child;
pub mod generator;
pub mod migration;
/// Describes whether a storage transaction should be committed or rolled back.
pub enum TransactionOutcome<T> {
/// Transaction should be committed.
Commit(T),
/// Transaction should be rolled back.
Rollback(T),
}
/// Execute the supplied function in a new storage transaction.
///
/// All changes to storage performed by the supplied function are discarded if the returned
/// outcome is `TransactionOutcome::Rollback`.
///
/// Transactions can be nested to any depth. Commits happen to the parent transaction.
pub fn with_transaction<R>(f: impl FnOnce() -> TransactionOutcome<R>) -> R {
use sp_io::storage::{
start_transaction, commit_transaction, rollback_transaction,
};
use TransactionOutcome::*;
start_transaction();
match f() {
Commit(res) => { commit_transaction(); res },
Rollback(res) => { rollback_transaction(); res },
}
}
/// A trait for working with macro-generated storage values under the substrate storage API.
///
/// Details on implementation can be found at