Implement 'transactional' annotation for runtime functions. (#6763)

* Implement 'transactional' annotation for runtime functions.

* Allow function attributes for dispatchable calls in decl_module.

* decl_module docs: add transactional function example.

* decl_module docs: add function attributes notes.

* Fix license header.
This commit is contained in:
Shaopeng Wang
2020-08-12 21:21:36 +12:00
committed by GitHub
parent c0ebb00fd3
commit a531c5b762
5 changed files with 164 additions and 7 deletions
@@ -17,9 +17,11 @@
use codec::{Encode, Decode, EncodeLike};
use frame_support::{
StorageMap, StorageValue, storage::{with_transaction, TransactionOutcome::*},
assert_ok, assert_noop, dispatch::{DispatchError, DispatchResult}, transactional, StorageMap, StorageValue,
storage::{with_transaction, TransactionOutcome::*},
};
use sp_io::TestExternalities;
use sp_std::result;
pub trait Trait {
type Origin;
@@ -27,7 +29,20 @@ pub trait Trait {
}
frame_support::decl_module! {
pub struct Module<T: Trait> for enum Call where origin: T::Origin {}
pub struct Module<T: Trait> for enum Call where origin: T::Origin {
#[weight = 0]
#[transactional]
fn value_commits(_origin, v: u32) {
Value::set(v);
}
#[weight = 0]
#[transactional]
fn value_rollbacks(_origin, v: u32) -> DispatchResult {
Value::set(v);
Err(DispatchError::Other("nah"))
}
}
}
frame_support::decl_storage!{
@@ -37,6 +52,11 @@ frame_support::decl_storage!{
}
}
struct Runtime;
impl Trait for Runtime {
type Origin = u32;
type BlockNumber = u32;
}
#[test]
fn storage_transaction_basic_commit() {
@@ -157,3 +177,36 @@ fn storage_transaction_commit_then_rollback() {
assert_eq!(Map::get("val3"), 0);
});
}
#[test]
fn transactional_annotation() {
#[transactional]
fn value_commits(v: u32) -> result::Result<u32, &'static str> {
Value::set(v);
Ok(v)
}
#[transactional]
fn value_rollbacks(v: u32) -> result::Result<u32, &'static str> {
Value::set(v);
Err("nah")
}
TestExternalities::default().execute_with(|| {
assert_ok!(value_commits(2), 2);
assert_eq!(Value::get(), 2);
assert_noop!(value_rollbacks(3), "nah");
});
}
#[test]
fn transactional_annotation_in_decl_module() {
TestExternalities::default().execute_with(|| {
let origin = 0;
assert_ok!(<Module<Runtime>>::value_commits(origin, 2));
assert_eq!(Value::get(), 2);
assert_noop!(<Module<Runtime>>::value_rollbacks(origin, 3), "nah");
});
}