Files
pezkuwi-subxt/substrate/frame/support/test/tests/storage_transaction.rs
T
Alexander Theißen bb2df2122e 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>
2020-06-23 11:17:53 +02:00

160 lines
3.6 KiB
Rust

// This file is part of Substrate.
// Copyright (C) 2020 Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: Apache-2.0
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use codec::{Encode, Decode, EncodeLike};
use frame_support::{
StorageMap, StorageValue, storage::{with_transaction, TransactionOutcome::*},
};
use sp_io::TestExternalities;
pub trait Trait {
type Origin;
type BlockNumber: Encode + Decode + EncodeLike + Default + Clone;
}
frame_support::decl_module! {
pub struct Module<T: Trait> for enum Call where origin: T::Origin {}
}
frame_support::decl_storage!{
trait Store for Module<T: Trait> as StorageTransactions {
pub Value: u32;
pub Map: map hasher(twox_64_concat) String => u32;
}
}
#[test]
fn storage_transaction_basic_commit() {
TestExternalities::default().execute_with(|| {
assert_eq!(Value::get(), 0);
assert!(!Map::contains_key("val0"));
with_transaction(|| {
Value::set(99);
Map::insert("val0", 99);
assert_eq!(Value::get(), 99);
assert_eq!(Map::get("val0"), 99);
Commit(())
});
assert_eq!(Value::get(), 99);
assert_eq!(Map::get("val0"), 99);
});
}
#[test]
fn storage_transaction_basic_rollback() {
TestExternalities::default().execute_with(|| {
assert_eq!(Value::get(), 0);
assert_eq!(Map::get("val0"), 0);
with_transaction(|| {
Value::set(99);
Map::insert("val0", 99);
assert_eq!(Value::get(), 99);
assert_eq!(Map::get("val0"), 99);
Rollback(())
});
assert_eq!(Value::get(), 0);
assert_eq!(Map::get("val0"), 0);
});
}
#[test]
fn storage_transaction_rollback_then_commit() {
TestExternalities::default().execute_with(|| {
Value::set(1);
Map::insert("val1", 1);
with_transaction(|| {
Value::set(2);
Map::insert("val1", 2);
Map::insert("val2", 2);
with_transaction(|| {
Value::set(3);
Map::insert("val1", 3);
Map::insert("val2", 3);
Map::insert("val3", 3);
assert_eq!(Value::get(), 3);
assert_eq!(Map::get("val1"), 3);
assert_eq!(Map::get("val2"), 3);
assert_eq!(Map::get("val3"), 3);
Rollback(())
});
assert_eq!(Value::get(), 2);
assert_eq!(Map::get("val1"), 2);
assert_eq!(Map::get("val2"), 2);
assert_eq!(Map::get("val3"), 0);
Commit(())
});
assert_eq!(Value::get(), 2);
assert_eq!(Map::get("val1"), 2);
assert_eq!(Map::get("val2"), 2);
assert_eq!(Map::get("val3"), 0);
});
}
#[test]
fn storage_transaction_commit_then_rollback() {
TestExternalities::default().execute_with(|| {
Value::set(1);
Map::insert("val1", 1);
with_transaction(|| {
Value::set(2);
Map::insert("val1", 2);
Map::insert("val2", 2);
with_transaction(|| {
Value::set(3);
Map::insert("val1", 3);
Map::insert("val2", 3);
Map::insert("val3", 3);
assert_eq!(Value::get(), 3);
assert_eq!(Map::get("val1"), 3);
assert_eq!(Map::get("val2"), 3);
assert_eq!(Map::get("val3"), 3);
Commit(())
});
assert_eq!(Value::get(), 3);
assert_eq!(Map::get("val1"), 3);
assert_eq!(Map::get("val2"), 3);
assert_eq!(Map::get("val3"), 3);
Rollback(())
});
assert_eq!(Value::get(), 1);
assert_eq!(Map::get("val1"), 1);
assert_eq!(Map::get("val2"), 0);
assert_eq!(Map::get("val3"), 0);
});
}