Add Limit to Tranasctional Layers (#10808)

* introduce hard limit to transactional

* add single layer transactional

* remove single_transactional

* Update mod.rs

* add tests

* maybe fix contracts cc @athei

* fmt

* fix contract logic

* Update frame/contracts/src/exec.rs

Co-authored-by: Alexander Theißen <alex.theissen@me.com>

* Update exec.rs

* add unchecked and custom errors

* Update lib.rs

* Apply suggestions from code review

Co-authored-by: Alexander Theißen <alex.theissen@me.com>

* Replace storage access by atomics

Co-authored-by: Alexander Theißen <alex.theissen@me.com>
This commit is contained in:
Shawn Tabrizi
2022-04-02 13:12:54 -04:00
committed by GitHub
parent 2d3ee74805
commit 96ee61179a
5 changed files with 275 additions and 111 deletions
+21 -8
View File
@@ -774,14 +774,27 @@ where
// All changes performed by the contract are executed under a storage transaction.
// This allows for roll back on error. Changes to the cached contract_info are
// comitted or rolled back when popping the frame.
let (success, output) = with_transaction(|| {
let output = do_transaction();
match &output {
Ok(result) if !result.did_revert() => TransactionOutcome::Commit((true, output)),
_ => TransactionOutcome::Rollback((false, output)),
}
});
// committed or rolled back when popping the frame.
//
// `with_transactional` may return an error caused by a limit in the
// transactional storage depth.
let transaction_outcome =
with_transaction(|| -> TransactionOutcome<Result<_, DispatchError>> {
let output = do_transaction();
match &output {
Ok(result) if !result.did_revert() =>
TransactionOutcome::Commit(Ok((true, output))),
_ => TransactionOutcome::Rollback(Ok((false, output))),
}
});
let (success, output) = match transaction_outcome {
// `with_transactional` executed successfully, and we have the expected output.
Ok((success, output)) => (success, output),
// `with_transactional` returned an error, and we propagate that error and note no state
// has changed.
Err(error) => (false, Err(error.into())),
};
self.pop_frame(success);
output
}