Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
parity
Mirrored projects
ink
Commits
b66ab319
Unverified
Commit
b66ab319
authored
Jul 24, 2019
by
Hero Bird
Committed by
GitHub
Jul 24, 2019
Browse files
Enhance Flush (#136)
* [core] Enhance Flush trait to make it work with SyncCell and SyncChunk * apply rustfmt
parent
7948d23b
Changes
23
Hide whitespace changes
Inline
Side-by-side
cli/src/cmd/new.rs
View file @
b66ab319
...
...
@@ -27,13 +27,13 @@ use std::{
fs
,
io
::{
Cursor
,
Read
,
Seek
,
SeekFrom
,
Write
,
},
path
,
};
use
std
::
io
::
Read
;
/// Initializes a project structure for the `lang` abstraction layer.
fn
initialize_for_lang
(
name
:
&
str
)
->
Result
<
()
>
{
...
...
core/src/env/api.rs
View file @
b66ab319
...
...
@@ -17,8 +17,8 @@
use
super
::
ContractEnvStorage
;
use
crate
::{
env
::{
EnvStorage
as
_
,
traits
::
Env
,
EnvStorage
as
_
,
},
memory
::
vec
::
Vec
,
storage
::
Key
,
...
...
core/src/env/srml/mod.rs
View file @
b66ab319
...
...
@@ -24,6 +24,6 @@ pub use self::types::DefaultSrmlTypes;
#[cfg(not(feature
=
"test-env"
))]
pub
use
self
::
srml_only
::{
sys
,
SrmlEnvStorage
,
SrmlEnv
,
SrmlEnvStorage
,
};
core/src/env/srml/srml_only/impls.rs
View file @
b66ab319
...
...
@@ -16,9 +16,7 @@
use
crate
::{
env
::{
srml
::{
sys
,
},
srml
::
sys
,
Env
,
EnvStorage
,
EnvTypes
,
...
...
@@ -26,9 +24,7 @@ use crate::{
memory
::
vec
::
Vec
,
storage
::
Key
,
};
use
core
::{
marker
::
PhantomData
,
};
use
core
::
marker
::
PhantomData
;
use
parity_codec
::
Decode
;
/// Load the contents of the scratch buffer
...
...
@@ -78,7 +74,7 @@ pub struct SrmlEnv<T>
where
T
:
EnvTypes
,
{
marker
:
PhantomData
<
fn
()
->
T
>
,
marker
:
PhantomData
<
fn
()
->
T
>
,
}
impl
<
T
>
EnvTypes
for
SrmlEnv
<
T
>
...
...
@@ -123,10 +119,18 @@ where
(
caller
,
ext_caller
,
<
Self
as
EnvTypes
>
::
AccountId
),
(
random_seed
,
ext_random_seed
,
<
Self
as
EnvTypes
>
::
Hash
),
(
now
,
ext_now
,
<
Self
as
EnvTypes
>
::
Moment
),
(
block_number
,
ext_block_number
,
<
Self
as
EnvTypes
>
::
BlockNumber
),
(
block_number
,
ext_block_number
,
<
Self
as
EnvTypes
>
::
BlockNumber
),
(
gas_price
,
ext_gas_price
,
<
Self
as
EnvTypes
>
::
Balance
),
(
gas_left
,
ext_gas_left
,
<
Self
as
EnvTypes
>
::
Balance
),
(
value_transferred
,
ext_value_transferred
,
<
Self
as
EnvTypes
>
::
Balance
)
(
value_transferred
,
ext_value_transferred
,
<
Self
as
EnvTypes
>
::
Balance
)
);
unsafe
fn
r
#
return
(
data
:
&
[
u8
])
->
!
{
...
...
core/src/env/srml/srml_only/mod.rs
View file @
b66ab319
...
...
@@ -18,6 +18,6 @@ mod impls;
pub
mod
sys
;
pub
use
self
::
impls
::{
SrmlEnvStorage
,
SrmlEnv
,
SrmlEnvStorage
,
};
core/src/env/test.rs
View file @
b66ab319
...
...
@@ -17,10 +17,10 @@
//! Public api to interact with the special testing environment.
use
crate
::
env
::{
traits
::
EnvTypes
,
ContractEnv
,
ContractEnvStorage
,
};
use
crate
::
env
::
traits
::
EnvTypes
;
/// Returns the total number of reads to all storage entries.
pub
fn
total_reads
()
->
u64
{
...
...
core/src/env/test_env.rs
View file @
b66ab319
...
...
@@ -27,7 +27,10 @@ use core::cell::{
Cell
,
RefCell
,
};
use
parity_codec
::{
Decode
,
Encode
};
use
parity_codec
::{
Decode
,
Encode
,
};
use
std
::
marker
::
PhantomData
;
/// A wrapper for the generic bytearray used for data in contract events.
...
...
@@ -410,7 +413,7 @@ thread_local! {
/// Test environment for testing SRML contract off-chain.
pub
struct
TestEnv
<
T
>
{
marker
:
PhantomData
<
fn
()
->
T
>
marker
:
PhantomData
<
fn
()
->
T
>
,
}
macro_rules!
impl_env_setters_for_test_env
{
...
...
@@ -423,7 +426,10 @@ macro_rules! impl_env_setters_for_test_env {
}
}
impl
<
T
>
TestEnv
<
T
>
where
T
:
EnvTypes
{
impl
<
T
>
TestEnv
<
T
>
where
T
:
EnvTypes
,
{
/// Resets the test environment as if no contract execution happened so far.
pub
fn
reset
()
{
TEST_ENV_DATA
.with
(|
test_env
|
test_env
.borrow_mut
()
.reset
())
...
...
@@ -447,7 +453,8 @@ impl<T> TestEnv<T> where T: EnvTypes {
/// Sets the input data for the next contract invocation.
pub
fn
set_input
(
input_bytes
:
&
[
u8
])
{
TEST_ENV_DATA
.with
(|
test_env
|
test_env
.borrow_mut
()
.set_input
(
input_bytes
.to_vec
()))
TEST_ENV_DATA
.with
(|
test_env
|
test_env
.borrow_mut
()
.set_input
(
input_bytes
.to_vec
()))
}
impl_env_setters_for_test_env!
(
...
...
@@ -494,7 +501,9 @@ where
type
BlockNumber
=
<
T
as
EnvTypes
>
::
BlockNumber
;
}
impl
<
T
>
Env
for
TestEnv
<
T
>
where
T
:
EnvTypes
impl
<
T
>
Env
for
TestEnv
<
T
>
where
T
:
EnvTypes
,
{
impl_env_getters_for_test_env!
(
(
address
,
T
::
AccountId
),
...
...
core/src/storage/cell/sync_cell.rs
View file @
b66ab319
...
...
@@ -305,12 +305,15 @@ impl<T> parity_codec::Decode for SyncCell<T> {
impl
<
T
>
Flush
for
SyncCell
<
T
>
where
T
:
parity_codec
::
Encode
,
T
:
parity_codec
::
Encode
+
Flush
,
{
fn
flush
(
&
mut
self
)
{
if
self
.cache
.is_dirty
()
{
match
self
.cache
.get
()
{
Some
(
val
)
=>
self
.cell
.store
(
val
),
match
self
.cache
.get_mut
()
{
Some
(
val
)
=>
{
self
.cell
.store
(
val
);
val
.flush
();
},
None
=>
self
.cell
.clear
(),
}
self
.cache
.mark_clean
();
...
...
core/src/storage/chunk/sync_chunk/chunk.rs
View file @
b66ab319
...
...
@@ -47,12 +47,15 @@ pub struct SyncChunk<T> {
impl
<
T
>
Flush
for
SyncChunk
<
T
>
where
T
:
parity_codec
::
Encode
,
T
:
parity_codec
::
Encode
+
Flush
,
{
fn
flush
(
&
mut
self
)
{
for
(
n
,
dirty_val
)
in
self
.cache
.iter_dirty
()
{
match
dirty_val
.get
()
{
Some
(
val
)
=>
self
.chunk
.store
(
n
,
val
),
match
dirty_val
.get_mut
()
{
Some
(
val
)
=>
{
self
.chunk
.store
(
n
,
val
);
val
.flush
();
}
None
=>
self
.chunk
.clear
(
n
),
}
dirty_val
.mark_clean
();
...
...
core/src/storage/collections/bitvec/block.rs
View file @
b66ab319
...
...
@@ -19,6 +19,7 @@ use parity_codec::{
Decode
,
Encode
,
};
use
crate
::
storage
::
Flush
;
/// A block of 1024 bits.
#[derive(Debug,
Copy,
Clone,
Encode,
Decode)]
...
...
@@ -27,6 +28,10 @@ pub struct BitBlock {
packs
:
[
BitPack
;
Self
::
PACKS
as
usize
],
}
impl
Flush
for
BitBlock
{
fn
flush
(
&
mut
self
)
{}
}
/// Error indicating an invalid bit pack index.
#[derive(Debug,
Copy,
Clone)]
struct
InvalidBitBlockIndex
;
...
...
core/src/storage/collections/hash_map/impls.rs
View file @
b66ab319
...
...
@@ -77,6 +77,19 @@ pub enum Entry<K, V> {
Removed
,
}
impl
<
K
,
V
>
Flush
for
Entry
<
K
,
V
>
where
K
:
parity_codec
::
Encode
+
Flush
,
V
:
parity_codec
::
Encode
+
Flush
,
{
fn
flush
(
&
mut
self
)
{
match
self
{
Entry
::
Occupied
(
occupied
)
=>
occupied
.flush
(),
Entry
::
Removed
=>
(),
}
}
}
/// An occupied entry of a storage map.
#[derive(Debug,
Clone,
PartialEq,
Eq,
parity_codec::Encode,
parity_codec::Decode)]
pub
struct
OccupiedEntry
<
K
,
V
>
{
...
...
@@ -86,10 +99,21 @@ pub struct OccupiedEntry<K, V> {
val
:
V
,
}
impl
<
K
,
V
>
Flush
for
OccupiedEntry
<
K
,
V
>
where
K
:
parity_codec
::
Encode
+
Flush
,
V
:
parity_codec
::
Encode
+
Flush
,
{
fn
flush
(
&
mut
self
)
{
self
.key
.flush
();
self
.val
.flush
();
}
}
impl
<
K
,
V
>
Flush
for
HashMap
<
K
,
V
>
where
K
:
parity_codec
::
Encode
,
V
:
parity_codec
::
Encode
,
K
:
parity_codec
::
Encode
+
Flush
,
V
:
parity_codec
::
Encode
+
Flush
,
{
fn
flush
(
&
mut
self
)
{
self
.len
.flush
();
...
...
core/src/storage/collections/stash/impls.rs
View file @
b66ab319
...
...
@@ -82,6 +82,14 @@ struct StashHeader {
max_len
:
u32
,
}
impl
Flush
for
StashHeader
{
fn
flush
(
&
mut
self
)
{
self
.next_vacant
.flush
();
self
.len
.flush
();
self
.max_len
.flush
();
}
}
/// Iterator over the values of a stash.
#[derive(Debug)]
pub
struct
Values
<
'a
,
T
>
{
...
...
@@ -98,7 +106,7 @@ impl<'a, T> Values<'a, T> {
impl
<
T
>
Flush
for
Stash
<
T
>
where
T
:
Encode
,
T
:
Encode
+
Flush
,
{
fn
flush
(
&
mut
self
)
{
self
.header
.flush
();
...
...
@@ -222,6 +230,18 @@ enum Entry<T> {
Occupied
(
T
),
}
impl
<
T
>
Flush
for
Entry
<
T
>
where
T
:
Flush
,
{
fn
flush
(
&
mut
self
)
{
match
self
{
Entry
::
Vacant
(
_
)
=>
(),
Entry
::
Occupied
(
occupied
)
=>
occupied
.flush
(),
}
}
}
impl
<
T
>
Encode
for
Stash
<
T
>
{
fn
encode_to
<
W
:
parity_codec
::
Output
>
(
&
self
,
dest
:
&
mut
W
)
{
self
.header
.encode_to
(
dest
);
...
...
core/src/storage/collections/vec/impls.rs
View file @
b66ab319
...
...
@@ -76,7 +76,7 @@ impl<'a, T> Iter<'a, T> {
impl
<
T
>
Flush
for
Vec
<
T
>
where
T
:
parity_codec
::
Encode
,
T
:
parity_codec
::
Encode
+
Flush
,
{
fn
flush
(
&
mut
self
)
{
self
.len
.flush
();
...
...
core/src/storage/flush.rs
View file @
b66ab319
...
...
@@ -25,7 +25,7 @@
///
/// # Implementation Hints
///
/// Caching types provided by
pDSL
are `SyncCell` for caching of a single data
/// Caching types provided by
ink!
are `SyncCell` for caching of a single data
/// and `SyncChunk` for caching an array of data.
///
/// All abstractions built upon them that do not have their own caching mechanism
...
...
@@ -33,5 +33,190 @@
/// `storage::Vec` or `storage::Value`.
pub
trait
Flush
{
/// Flushes the cached state back to the contract storage, if any.
///
/// # Note
///
/// Needs to take `self` by `&mut` since `SyncChunk` and `SyncCell`
/// and potentially other abstraction facilities are required to
/// write back their cached values which is a mutable operation.
fn
flush
(
&
mut
self
);
}
macro_rules!
impl_empty_flush_for
{
(
$
(
$ty:ty
),
*
)
=>
{
$
(
impl
Flush
for
$ty
{
fn
flush
(
&
mut
self
)
{}
}
)
*
};
}
impl_empty_flush_for!
{
u8
,
u16
,
u32
,
u64
,
u128
,
usize
,
i8
,
i16
,
i32
,
i64
,
i128
,
isize
,
bool
,
char
,
str
}
macro_rules!
impl_tuple_flush_for
{
(
$
((
$n:tt
,
$name:ident
)),
*
)
=>
{
impl
<
$
(
$name
),
*
>
Flush
for
(
$
(
$name
,)
*
)
where
$
(
$name
:
Flush
,
)
*
{
fn
flush
(
&
mut
self
)
{
$
(
self
.
$n
.flush
();
)
*
}
}
}
}
impl_tuple_flush_for!
();
impl_tuple_flush_for!
((
0
,
A
));
impl_tuple_flush_for!
((
0
,
A
),
(
1
,
B
));
impl_tuple_flush_for!
((
0
,
A
),
(
1
,
B
),
(
2
,
C
));
impl_tuple_flush_for!
((
0
,
A
),
(
1
,
B
),
(
2
,
C
),
(
3
,
D
));
impl_tuple_flush_for!
((
0
,
A
),
(
1
,
B
),
(
2
,
C
),
(
3
,
D
),
(
4
,
E
));
impl_tuple_flush_for!
((
0
,
A
),
(
1
,
B
),
(
2
,
C
),
(
3
,
D
),
(
4
,
E
),
(
5
,
F
));
impl_tuple_flush_for!
((
0
,
A
),
(
1
,
B
),
(
2
,
C
),
(
3
,
D
),
(
4
,
E
),
(
5
,
F
),
(
6
,
G
));
impl_tuple_flush_for!
(
(
0
,
A
),
(
1
,
B
),
(
2
,
C
),
(
3
,
D
),
(
4
,
E
),
(
5
,
F
),
(
6
,
G
),
(
7
,
H
)
);
macro_rules!
impl_array_flush_for
{
(
$
(
$n:literal
),
*
)
=>
{
$
(
impl
<
T
>
Flush
for
[
T
;
$n
]
where
T
:
Flush
,
{
fn
flush
(
&
mut
self
)
{
for
elem
in
&
mut
self
[
..
]
{
elem
.flush
()
}
}
}
)
*
}
}
#[rustfmt::skip]
impl_array_flush_for!
(
0
,
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
,
10
,
11
,
12
,
13
,
14
,
15
,
16
,
17
,
18
,
19
,
20
,
21
,
22
,
23
,
24
,
25
,
26
,
27
,
28
,
29
,
30
,
31
,
32
);
impl
<
T
>
Flush
for
[
T
]
where
T
:
Flush
,
{
fn
flush
(
&
mut
self
)
{
for
elem
in
self
{
elem
.flush
()
}
}
}
impl
<
T
>
Flush
for
Option
<
T
>
where
T
:
Flush
,
{
fn
flush
(
&
mut
self
)
{
match
self
{
Some
(
val
)
=>
val
.flush
(),
None
=>
(),
}
}
}
impl
<
T
,
E
>
Flush
for
Result
<
T
,
E
>
where
T
:
Flush
,
E
:
Flush
,
{
fn
flush
(
&
mut
self
)
{
match
self
{
Ok
(
val
)
=>
val
.flush
(),
Err
(
err
)
=>
err
.flush
(),
}
}
}
impl
<
T
>
Flush
for
crate
::
memory
::
vec
::
Vec
<
T
>
where
T
:
Flush
,
{
fn
flush
(
&
mut
self
)
{
for
elem
in
self
{
elem
.flush
()
}
}
}
impl
Flush
for
crate
::
memory
::
string
::
String
{
fn
flush
(
&
mut
self
)
{
// Note: Strings contain only characters that need no flushing.
}
}
impl
<
K
,
V
>
Flush
for
crate
::
memory
::
collections
::
btree_map
::
BTreeMap
<
K
,
V
>
where
V
:
Flush
,
{
fn
flush
(
&
mut
self
)
{
for
(
_key
,
val
)
in
self
{
// We do not need to write back keys since they are immutable.
val
.flush
();
}
}
}
impl
<
T
>
Flush
for
crate
::
memory
::
collections
::
btree_set
::
BTreeSet
<
T
>
{
fn
flush
(
&
mut
self
)
{
// Note: Values within a `BTreeSet` are immutable and thus need not be flushed.
}
}
impl
<
T
>
Flush
for
crate
::
memory
::
collections
::
linked_list
::
LinkedList
<
T
>
where
T
:
Flush
,
{
fn
flush
(
&
mut
self
)
{
for
elem
in
self
{
elem
.flush
()
}
}
}
impl
<
T
>
Flush
for
crate
::
memory
::
collections
::
vec_deque
::
VecDeque
<
T
>
where
T
:
Flush
,
{
fn
flush
(
&
mut
self
)
{
for
elem
in
self
{
elem
.flush
()
}
}
}
impl
<
T
>
Flush
for
crate
::
memory
::
collections
::
binary_heap
::
BinaryHeap
<
T
>
where
T
:
Flush
,
{
fn
flush
(
&
mut
self
)
{
// Note: Values within a `BinaryHeap` are immutable and thus need not be flushed.
}
}
core/src/storage/key.rs
View file @
b66ab319
...
...
@@ -163,45 +163,39 @@ impl KeyDiff {
}
macro_rules!
impl_add_sub_for_key
{
(
$prim:ty
)
=>
{
impl
core
::
ops
::
Add
<
$prim
>
for
Key
{
type
Output
=
Self
;
(
$prim:ty
)
=>
{
impl
core
::
ops
::
Add
<
$prim
>
for
Key
{
type
Output
=
Self
;
fn
add
(
self
,
rhs
:
$prim
)
->
Self
::
Output
{
let
mut
result
=
self
;
result
+=
rhs
;
result
}
}
fn
add
(
self
,
rhs
:
$prim
)
->
Self
::
Output
{
let
mut
result
=
self
;
result
+=
rhs
;
result
}
}
impl
core
::
ops
::
AddAssign
<
$prim
>
for
Key
{
fn
add_assign
(
&
mut
self
,
rhs
:
$prim
)
{
byte_utils
::
bytes_add_bytes
(
self
.as_bytes_mut
(),
&
(
rhs
.to_be_bytes
())
);
}
}
impl
core
::
ops
::
AddAssign
<
$prim
>
for
Key
{
fn
add_assign
(
&
mut
self
,
rhs
:
$prim
)
{
byte_utils
::
bytes_add_bytes
(
self
.as_bytes_mut
(),
&
(
rhs
.to_be_bytes
()));
}
}
impl
core
::
ops
::
Sub
<
$prim
>
for
Key
{
type
Output
=
Self
;
impl
core
::
ops
::
Sub
<
$prim
>
for
Key
{
type
Output
=
Self
;
fn
sub
(
self
,
rhs
:
$prim
)
->
Self
::
Output
{
let
mut
result
=
self
;
result
-=
rhs
;
result
}
}
fn
sub
(
self
,
rhs
:
$prim
)
->
Self
::
Output
{
let
mut
result
=
self
;
result
-=
rhs
;
result
}
}
impl
core
::
ops
::
SubAssign
<
$prim
>
for
Key
{
fn
sub_assign
(
&
mut
self
,
rhs
:
$prim
)
{
byte_utils
::
bytes_sub_bytes
(
self
.as_bytes_mut
(),
&
rhs
.to_be_bytes
()
);
}
}
};
impl
core
::
ops
::
SubAssign
<
$prim
>
for
Key
{
fn
sub_assign
(
&
mut
self
,
rhs
:
$prim
)
{
byte_utils
::
bytes_sub_bytes
(
self
.as_bytes_mut
(),
&
rhs
.to_be_bytes
());
}
}
};
}
impl_add_sub_for_key!
(
u32
);
...
...
core/src/storage/value.rs
View file @
b66ab319
...
...
@@ -160,7 +160,7 @@ where
impl
<
T
>
Flush
for
Value
<
T
>
where
T
:
Encode
,
T
:
Encode
+
Flush
,
{
fn
flush
(
&
mut
self
)
{
self
.cell
.flush
()
...
...
lang/src/api.rs
View file @
b66ab319
...
...
@@ -22,8 +22,11 @@ use serde::{
Deserialize
,
Serialize
,
};
use
syn
::{
self
,
Result
};
use
std
::
convert
::
TryFrom
;
use
syn
::{
self
,
Result
,
};
/// Describes a message parameter or return type.