mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-26 14:37:57 +00:00
sp-api: Support nested transactions (#14447)
* sp-api: Support nested transactions Adds support for nested transactions in `sp-api` by using `execute_in_transaction`. This was working until a recent refactor, but this was actually not intended. However, supporting nested transactions is a worthwhile feature to have. So, this pr "brings it back" and adds a test to ensure it will not break. * Make clippy happy * Assert that the runtime api type is not unwind safe * Count number of transactions
This commit is contained in:
@@ -15,15 +15,20 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use sp_api::{Core, ProvideRuntimeApi};
|
||||
use sp_runtime::traits::{HashFor, Header as HeaderT};
|
||||
use std::panic::UnwindSafe;
|
||||
|
||||
use sp_api::{ApiExt, Core, ProvideRuntimeApi};
|
||||
use sp_runtime::{
|
||||
traits::{HashFor, Header as HeaderT},
|
||||
TransactionOutcome,
|
||||
};
|
||||
use sp_state_machine::{
|
||||
create_proof_check_backend, execution_proof_check_on_trie_backend, ExecutionStrategy,
|
||||
};
|
||||
use substrate_test_runtime_client::{
|
||||
prelude::*,
|
||||
runtime::{Block, Header, TestAPI, Transfer},
|
||||
DefaultTestClientBuilderExt, TestClientBuilder,
|
||||
DefaultTestClientBuilderExt, TestClient, TestClientBuilder,
|
||||
};
|
||||
|
||||
use codec::Encode;
|
||||
@@ -187,3 +192,46 @@ fn disable_logging_works() {
|
||||
assert!(output.contains("Logging from native works"));
|
||||
}
|
||||
}
|
||||
|
||||
// Certain logic like the transaction handling is not unwind safe.
|
||||
//
|
||||
// Ensure that the type is not unwind safe!
|
||||
static_assertions::assert_not_impl_any!(<TestClient as ProvideRuntimeApi<_>>::Api: UnwindSafe);
|
||||
|
||||
#[test]
|
||||
fn ensure_transactional_works() {
|
||||
const KEY: &[u8] = b"test";
|
||||
|
||||
let client = TestClientBuilder::new().build();
|
||||
let best_hash = client.chain_info().best_hash;
|
||||
|
||||
let runtime_api = client.runtime_api();
|
||||
runtime_api.execute_in_transaction(|api| {
|
||||
api.write_key_value(best_hash, KEY.to_vec(), vec![1, 2, 3], false).unwrap();
|
||||
|
||||
api.execute_in_transaction(|api| {
|
||||
api.write_key_value(best_hash, KEY.to_vec(), vec![1, 2, 3, 4], false).unwrap();
|
||||
|
||||
TransactionOutcome::Commit(())
|
||||
});
|
||||
|
||||
TransactionOutcome::Commit(())
|
||||
});
|
||||
|
||||
let changes = runtime_api
|
||||
.into_storage_changes(&client.state_at(best_hash).unwrap(), best_hash)
|
||||
.unwrap();
|
||||
assert_eq!(changes.main_storage_changes[0].1, Some(vec![1, 2, 3, 4]));
|
||||
|
||||
let runtime_api = client.runtime_api();
|
||||
runtime_api.execute_in_transaction(|api| {
|
||||
assert!(api.write_key_value(best_hash, KEY.to_vec(), vec![1, 2, 3], true).is_err());
|
||||
|
||||
TransactionOutcome::Commit(())
|
||||
});
|
||||
|
||||
let changes = runtime_api
|
||||
.into_storage_changes(&client.state_at(best_hash).unwrap(), best_hash)
|
||||
.unwrap();
|
||||
assert_eq!(changes.main_storage_changes[0].1, Some(vec![1, 2, 3]));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user