state_machine no_std witness externalities (#6934)

* checkpoint before removing CT from change trie

* before trie backend without tx

* undo

* Started no transaction, but would need using a different root
calculation method, out of the scope of this pr, will roll back.

* Remove NoTransaction.

* partially address review.
dummy stats implementation for no_std.

* Remove ChangeTrieOverlay.

* modified function

* Remove witness_ext

* need noops changes root

* update from cumulus branch

* line break

* remove warning

* line break

* From review: renamings and stats active in no std (except time).

* include cache, exclude change trie cache with individual temporary bad looking
no_std check

* little test

* fuse imports and filter_map prepare_extrinsics_input_inner fold.

* put back ExtInner into Ext, awkward double proto for new function.

* Apply suggestions from code review

* Update primitives/state-machine/Cargo.toml

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>
This commit is contained in:
cheme
2020-09-11 12:11:25 +02:00
committed by GitHub
parent 45d26e7419
commit 232a30fdb4
18 changed files with 1209 additions and 794 deletions
+70 -1
View File
@@ -29,7 +29,7 @@ use codec::{Encode, Decode, Input, Error};
use sp_core::{offchain::KeyTypeId, ChangesTrieConfiguration, OpaqueMetadata, RuntimeDebug};
use sp_application_crypto::{ed25519, sr25519, ecdsa, RuntimeAppPublic};
use trie_db::{TrieMut, Trie};
use sp_trie::PrefixedMemoryDB;
use sp_trie::{PrefixedMemoryDB, StorageProof};
use sp_trie::trie_types::{TrieDB, TrieDBMut};
use sp_api::{decl_runtime_apis, impl_runtime_apis};
@@ -335,6 +335,8 @@ cfg_if! {
fn test_ecdsa_crypto() -> (ecdsa::AppSignature, ecdsa::AppPublic);
/// Run various tests against storage.
fn test_storage();
/// Check a witness.
fn test_witness(proof: StorageProof, root: crate::Hash);
/// Test that ensures that we can call a function that takes multiple
/// arguments.
fn test_multiple_arguments(data: Vec<u8>, other: Vec<u8>, num: u32);
@@ -384,6 +386,8 @@ cfg_if! {
fn test_ecdsa_crypto() -> (ecdsa::AppSignature, ecdsa::AppPublic);
/// Run various tests against storage.
fn test_storage();
/// Check a witness.
fn test_witness(proof: StorageProof, root: crate::Hash);
/// Test that ensures that we can call a function that takes multiple
/// arguments.
fn test_multiple_arguments(data: Vec<u8>, other: Vec<u8>, num: u32);
@@ -684,6 +688,10 @@ cfg_if! {
test_read_child_storage();
}
fn test_witness(proof: StorageProof, root: crate::Hash) {
test_witness(proof, root);
}
fn test_multiple_arguments(data: Vec<u8>, other: Vec<u8>, num: u32) {
assert_eq!(&data[..], &other[..]);
assert_eq!(data.len(), num as usize);
@@ -926,6 +934,10 @@ cfg_if! {
test_read_child_storage();
}
fn test_witness(proof: StorageProof, root: crate::Hash) {
test_witness(proof, root);
}
fn test_multiple_arguments(data: Vec<u8>, other: Vec<u8>, num: u32) {
assert_eq!(&data[..], &other[..]);
assert_eq!(data.len(), num as usize);
@@ -1099,6 +1111,34 @@ fn test_read_child_storage() {
assert_eq!(&v, &[0, 0, 0, 0]);
}
fn test_witness(proof: StorageProof, root: crate::Hash) {
use sp_externalities::Externalities;
let db: sp_trie::MemoryDB<crate::Hashing> = proof.into_memory_db();
let backend = sp_state_machine::TrieBackend::<_, crate::Hashing>::new(
db,
root,
);
let mut overlay = sp_state_machine::OverlayedChanges::default();
#[cfg(feature = "std")]
let mut offchain_overlay = Default::default();
let mut cache = sp_state_machine::StorageTransactionCache::<_, _, BlockNumber>::default();
let mut ext = sp_state_machine::Ext::new(
&mut overlay,
#[cfg(feature = "std")]
&mut offchain_overlay,
&mut cache,
&backend,
#[cfg(feature = "std")]
None,
#[cfg(feature = "std")]
None,
);
assert!(ext.storage(b"value3").is_some());
assert!(ext.storage_root().as_slice() == &root[..]);
ext.place_storage(vec![0], Some(vec![1]));
assert!(ext.storage_root().as_slice() != &root[..]);
}
#[cfg(test)]
mod tests {
use substrate_test_runtime_client::{
@@ -1157,4 +1197,33 @@ mod tests {
runtime_api.test_storage(&block_id).unwrap();
}
fn witness_backend() -> (sp_trie::MemoryDB<crate::Hashing>, crate::Hash) {
use sp_trie::TrieMut;
let mut root = crate::Hash::default();
let mut mdb = sp_trie::MemoryDB::<crate::Hashing>::default();
{
let mut trie = sp_trie::trie_types::TrieDBMut::new(&mut mdb, &mut root);
trie.insert(b"value3", &[142]).expect("insert failed");
trie.insert(b"value4", &[124]).expect("insert failed");
};
(mdb, root)
}
#[test]
fn witness_backend_works() {
let (db, root) = witness_backend();
let backend = sp_state_machine::TrieBackend::<_, crate::Hashing>::new(
db,
root,
);
let proof = sp_state_machine::prove_read(backend, vec![b"value3"]).unwrap();
let client = TestClientBuilder::new()
.set_execution_strategy(ExecutionStrategy::Both)
.build();
let runtime_api = client.runtime_api();
let block_id = BlockId::Number(client.chain_info().best_number);
runtime_api.test_witness(&block_id, proof, root).unwrap();
}
}