Switch contract storage to child trie (#2002)

This commit is contained in:
cheme
2019-03-22 18:01:06 +01:00
committed by Sergei Pepyakin
parent 704d2a49c7
commit dd47be51c3
23 changed files with 363 additions and 86 deletions
+39 -12
View File
@@ -24,7 +24,7 @@ use runtime_primitives::testing::{Digest, DigestItem, H256, Header, UintAuthorit
use runtime_primitives::traits::{BlakeTwo256, IdentityLookup};
use runtime_primitives::BuildStorage;
use runtime_io;
use srml_support::{StorageMap, StorageDoubleMap, assert_ok, impl_outer_event, impl_outer_dispatch,
use srml_support::{storage::child, StorageMap, assert_ok, impl_outer_event, impl_outer_dispatch,
impl_outer_origin, traits::Currency};
use substrate_primitives::Blake2Hasher;
use system::{self, Phase, EventRecord};
@@ -32,9 +32,13 @@ use {wabt, balances, consensus};
use hex_literal::*;
use assert_matches::assert_matches;
use crate::{
ContractAddressFor, GenesisConfig, Module, RawEvent, StorageOf,
Trait, ComputeDispatchFee
ContractAddressFor, GenesisConfig, Module, RawEvent,
Trait, ComputeDispatchFee, TrieIdGenerator, TrieId,
AccountInfo, AccountInfoOf,
};
use substrate_primitives::storage::well_known_keys;
use parity_codec::{Encode, Decode, KeyedVec};
use std::sync::atomic::{AtomicUsize, Ordering};
mod contract {
// Re-export contents of the root. This basically
@@ -68,7 +72,7 @@ impl system::Trait for Test {
type Hashing = BlakeTwo256;
type Digest = Digest;
type AccountId = u64;
type Lookup = IdentityLookup<u64>;
type Lookup = IdentityLookup<Self::AccountId>;
type Header = Header;
type Event = MetaEvent;
type Log = DigestItem;
@@ -97,6 +101,7 @@ impl Trait for Test {
type DetermineContractAddress = DummyContractAddressFor;
type Event = MetaEvent;
type ComputeDispatchFee = DummyComputeDispatchFee;
type TrieIdGenerator = DummyTrieIdGenerator;
type GasPayment = ();
}
@@ -111,6 +116,17 @@ impl ContractAddressFor<H256, u64> for DummyContractAddressFor {
}
}
static KEY_COUNTER: AtomicUsize = AtomicUsize::new(0);
pub struct DummyTrieIdGenerator;
impl TrieIdGenerator<u64> for DummyTrieIdGenerator {
fn trie_id(account_id: &u64) -> TrieId {
let mut res = KEY_COUNTER.fetch_add(1, Ordering::Relaxed).to_le_bytes().to_vec();
res.extend_from_slice(&account_id.to_le_bytes());
res
}
}
pub struct DummyComputeDispatchFee;
impl ComputeDispatchFee<Call, u64> for DummyComputeDispatchFee {
fn compute_dispatch_fee(call: &Call) -> u64 {
@@ -217,18 +233,29 @@ fn refunds_unused_gas() {
#[test]
fn account_removal_removes_storage() {
let unique_id1 = b"unique_id1";
let unique_id2 = b"unique_id2";
with_externalities(
&mut ExtBuilder::default().existential_deposit(100).build(),
|| {
// Setup two accounts with free balance above than exsistential threshold.
{
Balances::deposit_creating(&1, 110);
<StorageOf<Test>>::insert(&1, &b"foo".to_vec(), b"1".to_vec());
<StorageOf<Test>>::insert(&1, &b"bar".to_vec(), b"2".to_vec());
AccountInfoOf::<Test>::insert(1, &AccountInfo {
trie_id: unique_id1.to_vec(),
current_mem_stored: 0,
});
child::put(&unique_id1[..], &b"foo".to_vec(), &b"1".to_vec());
assert_eq!(child::get(&unique_id1[..], &b"foo".to_vec()), Some(b"1".to_vec()));
child::put(&unique_id1[..], &b"bar".to_vec(), &b"2".to_vec());
Balances::deposit_creating(&2, 110);
<StorageOf<Test>>::insert(&2, &b"hello".to_vec(), b"3".to_vec());
<StorageOf<Test>>::insert(&2, &b"world".to_vec(), b"4".to_vec());
AccountInfoOf::<Test>::insert(2, &AccountInfo {
trie_id: unique_id2.to_vec(),
current_mem_stored: 0,
});
child::put(&unique_id2[..], &b"hello".to_vec(), &b"3".to_vec());
child::put(&unique_id2[..], &b"world".to_vec(), &b"4".to_vec());
}
// Transfer funds from account 1 of such amount that after this transfer
@@ -240,15 +267,15 @@ fn account_removal_removes_storage() {
// Verify that all entries from account 1 is removed, while
// entries from account 2 is in place.
{
assert_eq!(<StorageOf<Test>>::get(&1, &b"foo".to_vec()), None);
assert_eq!(<StorageOf<Test>>::get(&1, &b"bar".to_vec()), None);
assert_eq!(child::get_raw(&unique_id1[..], &b"foo".to_vec()), None);
assert_eq!(child::get_raw(&unique_id1[..], &b"bar".to_vec()), None);
assert_eq!(
<StorageOf<Test>>::get(&2, &b"hello".to_vec()),
child::get(&unique_id2[..], &b"hello".to_vec()),
Some(b"3".to_vec())
);
assert_eq!(
<StorageOf<Test>>::get(&2, &b"world".to_vec()),
child::get(&unique_id2[..], &b"world".to_vec()),
Some(b"4".to_vec())
);
}