Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
81 commits
Select commit Hold shift + click to select a range
36c171c
Introduce basic skeleton for Polkador runtime.
gavofyork Jan 8, 2018
f79b7bb
Clean up the runtime skeleton.
gavofyork Jan 8, 2018
b48e053
Make initial runtime skeleton compile.
gavofyork Jan 8, 2018
4e25b24
Compile polkadot-runtime both for Wasm ad native, allowing for testin…
gavofyork Jan 9, 2018
b28402c
More fleshing out on runtime.
gavofyork Jan 9, 2018
bac50a4
Update native support.
gavofyork Jan 9, 2018
9a4360f
Fix warning.
gavofyork Jan 9, 2018
0890e72
Update gitignore
gavofyork Jan 9, 2018
4cf5fd1
Update path.
gavofyork Jan 9, 2018
12b15fd
Fix path.
gavofyork Jan 9, 2018
47260c2
Remove accidentally committed files.
gavofyork Jan 9, 2018
800eb20
Add wasm binaries.
gavofyork Jan 9, 2018
10eaefe
Fix test.
gavofyork Jan 9, 2018
24ba809
Native storage support API.
gavofyork Jan 9, 2018
36a49ff
Add environmental module
gavofyork Jan 10, 2018
50e7222
Add native environment to make native source-code compatible with wasm.
gavofyork Jan 10, 2018
3e17caa
Finish up & polish environment stuff.
gavofyork Jan 10, 2018
e807c9a
Avoid using reentrancy issues.
gavofyork Jan 10, 2018
402ae29
Add some docs and a test.
gavofyork Jan 10, 2018
762826b
Remove unneeded function.
gavofyork Jan 10, 2018
7e969c8
Documentation
gavofyork Jan 11, 2018
64b0670
Tweak docs
gavofyork Jan 11, 2018
d34f62a
Remove TODOs.
gavofyork Jan 11, 2018
89f35e3
Balance transfers + util methods.
gavofyork Jan 14, 2018
5e42240
Rejig tests and ensure authorities are addressed consistently.
gavofyork Jan 14, 2018
d97e2d6
Add marshaller for xfer function
gavofyork Jan 14, 2018
26ccc14
Transaction dispatch test.
gavofyork Jan 15, 2018
7258e1f
Minor fix.
gavofyork Jan 15, 2018
c02e335
Add test for ser/de transaction.
gavofyork Jan 15, 2018
28fa761
Add ser/de for header.
gavofyork Jan 15, 2018
cd93a37
Add tests for header ser/de
gavofyork Jan 16, 2018
b55095a
Introduce basic block decoding/execution framework.
gavofyork Jan 16, 2018
288f653
Introduce block decoding/execution framework (p2)
gavofyork Jan 16, 2018
c64976b
Big refactor.
gavofyork Jan 16, 2018
40e28fc
Split out joiner.
gavofyork Jan 16, 2018
ab37f64
Hide away support modules.
gavofyork Jan 16, 2018
4844086
Fix up wasm runtime.
gavofyork Jan 16, 2018
28d775d
use externalities for chain_id
gavofyork Jan 16, 2018
75cedd9
Clean up (Test)Externalities.
gavofyork Jan 16, 2018
0feadc6
Repot and introduce keccak-256 external.
gavofyork Jan 17, 2018
15ae775
Signing with crypto.
gavofyork Jan 17, 2018
5650997
fix unsafety hole in environmental using function
rphmeier Jan 17, 2018
7820149
Introduce Ed25519 crypto.
gavofyork Jan 17, 2018
4ef4239
Repotting.
gavofyork Jan 17, 2018
8fa858c
Merge branch 'signing-ring' into polkadot-runtime-skeleton
gavofyork Jan 17, 2018
78a22d4
Add ed25519_verify external.
gavofyork Jan 17, 2018
93f7aed
Introduce Ed25519 verify as an external.
gavofyork Jan 17, 2018
cdc1387
fix unsafety hole around unwinding
rphmeier Jan 17, 2018
0477b7e
Compile fixes.
gavofyork Jan 17, 2018
66c9384
use new environmental API
rphmeier Jan 17, 2018
121aa0b
Merge branch 'polkadot-runtime-skeleton' into environmental-api
rphmeier Jan 17, 2018
eebc071
Tests for ed25519 verify.
gavofyork Jan 18, 2018
5685173
Polish
gavofyork Jan 18, 2018
f3d415c
Introduce UncheckedTransaction & test.
gavofyork Jan 18, 2018
2c9cb7b
Implement basic block and tx processing
gavofyork Jan 18, 2018
eda7d71
Introduce static hex and valid signature for block test.
gavofyork Jan 18, 2018
fd9d8dc
Merge pull request #35 from paritytech/environmental-api
gavofyork Jan 18, 2018
e8cd918
Repot session.
gavofyork Jan 18, 2018
3d1ff94
comments.
gavofyork Jan 18, 2018
92a12f0
Refactor and timestamp test
gavofyork Jan 19, 2018
5523277
Remove fluff
gavofyork Jan 19, 2018
39128b7
Merge branch 'polkadot-runtime-skeleton' of github.com:paritytech/pol…
gavofyork Jan 19, 2018
9a8f61d
Remove fluff.
gavofyork Jan 19, 2018
90f965a
Staking eras and tests.
gavofyork Jan 19, 2018
58670fc
Implement sessions.
gavofyork Jan 19, 2018
999025f
Polish
gavofyork Jan 19, 2018
4fde6f0
Test sessions.
gavofyork Jan 19, 2018
9c8cafd
Introduce better hashing.
gavofyork Jan 19, 2018
ae5a9c9
Fix tests.
gavofyork Jan 19, 2018
639554c
Introduce staking.
gavofyork Jan 19, 2018
0e88dad
Tests for simple staking system.
gavofyork Jan 19, 2018
80aa38c
Build fix for wasm.
gavofyork Jan 19, 2018
ef5d78a
Fix tests.
gavofyork Jan 19, 2018
e068f44
Repotting and docs.
gavofyork Jan 19, 2018
2499910
Docs and licence.
gavofyork Jan 19, 2018
0c53f71
Documentation.
gavofyork Jan 19, 2018
850f7ee
Remove superfluous code.
gavofyork Jan 19, 2018
dde319c
Remove dummy key.
gavofyork Jan 19, 2018
17ef2d0
Remove other superfluous file.
gavofyork Jan 19, 2018
8adb7c6
Optimise with swap_remove
gavofyork Jan 20, 2018
cbd65cb
Merge remote-tracking branch 'origin/master' into polkadot-runtime-sk…
gavofyork Jan 23, 2018
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/target/
**/*.rs.bk
*.swp
runtime/**/target/
wasm-runtime/**/target/
**/._*
150 changes: 148 additions & 2 deletions Cargo.lock

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,16 @@ members = [
"candidate-agreement",
"client",
"collator",
"environmental",
"executor",
"primitives",
"rpc",
"rpc_servers",
"native-runtime",
"serializer",
"state_machine",
"validator",
]
exclude = [
"runtime"
"wasm-runtime"
]
4 changes: 4 additions & 0 deletions environmental/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[package]
name = "environmental"
version = "0.1.0"
authors = ["Parity Technologies <[email protected]>"]
272 changes: 272 additions & 0 deletions environmental/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,272 @@
// Copyright 2017 Parity Technologies (UK) Ltd.
// This file is part of Polkadot.

// Polkadot is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// Polkadot is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.

//! Safe global references to stack variables.
//!
//! Set up a global reference with environmental! macro giving it a name and type.
//! Use the `using` function scoped under its name to name a reference and call a function that
//! takes no parameters yet can access said reference through the similarly placed `with` function.
//!
//! # Examples
//!
//! ```
//! #[macro_use] extern crate environmental;
//! // create a place for the global reference to exist.
//! environmental!(counter: u32);
//! fn stuff() {
//! // do some stuff, accessing the named reference as desired.
//! counter::with(|i| *i += 1);
//! }
//! fn main() {
//! // declare a stack variable of the same type as our global declaration.
//! let mut counter_value = 41u32;
//! // call stuff, setting up our `counter` environment as a refrence to our counter_value var.
//! counter::using(&mut counter_value, stuff);
//! println!("The answer is {:?}", counter_value); // will print 42!
//! stuff(); // safe! doesn't do anything.
//! }
//! ```

use std::cell::RefCell;
use std::thread::LocalKey;

#[doc(hidden)]
pub fn using<T: ?Sized, R, F: FnOnce() -> R>(
global: &'static LocalKey<RefCell<Option<*mut T>>>,
protected: &mut T,
f: F
) -> R {
// store the `protected` reference as a pointer so we can provide it to logic running within
// `f`.
// while we record this pointer (while it's non-zero) we guarantee:
// - it will only be used once at any time (no reentrancy);
// - that no other thread will use it; and
// - that we do not use the original mutating reference while the pointer.
// exists.
global.with(|r| {
let original = {
let mut global = r.borrow_mut();
::std::mem::replace(&mut *global, Some(protected as _))
};

// even if `f` panics the original will be replaced.
struct ReplaceOriginal<'a, T: 'a + ?Sized> {
original: Option<*mut T>,
global: &'a RefCell<Option<*mut T>>,
}

impl<'a, T: 'a + ?Sized> Drop for ReplaceOriginal<'a, T> {
fn drop(&mut self) {
*self.global.borrow_mut() = self.original.take();
}
}

let _guard = ReplaceOriginal {
original,
global: r,
};

f()
})
}

#[doc(hidden)]
pub fn with<T: ?Sized, R, F: FnOnce(&mut T) -> R>(
global: &'static LocalKey<RefCell<Option<*mut T>>>,
mutator: F,
) -> Option<R> {
global.with(|r| unsafe {
let ptr = r.borrow_mut();
match *ptr {
Some(ptr) => {
// safe because it's only non-zero when it's being called from using, which
// is holding on to the underlying reference (and not using it itself) safely.
Some(mutator(&mut *ptr))
}
None => None,
}
})
}

/// Declare a new global reference module whose underlying value does not contain references.
///
/// Will create a module of a given name that contains two functions:
/// * `pub fn using<R, F: FnOnce() -> R>(protected: &mut $t, f: F) -> R`
/// This executes `f`, returning its value. During the call, the module's reference is set to
/// be equal to `protected`.
/// * `pub fn with<R, F: FnOnce(&mut $t) -> R>(f: F) -> Option<R>`
/// This executes `f`, returning `Some` of its value if called from code that is being executed
/// as part of a `using` call. If not, it returns `None`. `f` is provided with one argument: the
/// same reference as provided to the most recent `using` call.
///
/// # Examples
///
/// Initializing the global context with a given value.
///
/// ```rust
/// #[macro_use] extern crate environmental;
/// environmental!(counter: u32);
/// fn main() {
/// let mut counter_value = 41u32;
/// counter::using(&mut counter_value, || {
/// let odd = counter::with(|value|
/// if *value % 2 == 1 {
/// *value += 1; true
/// } else {
/// *value -= 3; false
/// }).unwrap(); // safe because we're inside a counter::using
/// println!("counter was {}", match odd { true => "odd", _ => "even" });
/// });
///
/// println!("The answer is {:?}", counter_value); // 42
/// }
/// ```
///
/// Roughly the same, but with a trait object:
///
/// ```rust
/// #[macro_use] extern crate environmental;
///
/// trait Increment { fn increment(&mut self); }
///
/// impl Increment for i32 {
/// fn increment(&mut self) { *self += 1 }
/// }
///
/// environmental!(val: Increment + 'static);
///
/// fn main() {
/// let mut local = 0i32;
/// val::using(&mut local, || {
/// val::with(|v| for _ in 0..5 { v.increment() });
/// });
///
/// assert_eq!(local, 5);
/// }
/// ```
#[macro_export]
macro_rules! environmental {
($name:ident : $t:ty) => {
#[allow(non_camel_case_types)]
struct $name { __private_field: () }

thread_local!(static GLOBAL: ::std::cell::RefCell<Option<*mut $t>>
= ::std::cell::RefCell::new(None));

impl $name {
#[allow(unused_imports)]

pub fn using<R, F: FnOnce() -> R>(
protected: &mut $t,
f: F
) -> R {
$crate::using(&GLOBAL, protected, f)
}

pub fn with<R, F: FnOnce(&mut $t) -> R>(
f: F
) -> Option<R> {
$crate::with(&GLOBAL, |x| f(x))
}
}
};
}

#[cfg(test)]
mod tests {

#[test]
fn simple_works() {
environmental!(counter: u32);

fn stuff() { counter::with(|value| *value += 1); };

// declare a stack variable of the same type as our global declaration.
let mut local = 41u32;

// call stuff, setting up our `counter` environment as a refrence to our local counter var.
counter::using(&mut local, stuff);
assert_eq!(local, 42);
stuff(); // safe! doesn't do anything.
}

#[test]
fn overwrite_with_lesser_lifetime() {
environmental!(items: Vec<u8>);

let mut local_items = vec![1, 2, 3];
items::using(&mut local_items, || {
let dies_at_end = vec![4, 5, 6];
items::with(|items| *items = dies_at_end);
});

assert_eq!(local_items, vec![4, 5, 6]);
}

#[test]
fn declare_with_trait_object() {
trait Foo {
fn get(&self) -> i32;
fn set(&mut self, x: i32);
}

impl Foo for i32 {
fn get(&self) -> i32 { *self }
fn set(&mut self, x: i32) { *self = x }
}

environmental!(foo: Foo + 'static);

fn stuff() {
foo::with(|value| {
let new_val = value.get() + 1;
value.set(new_val);
});
}

let mut local = 41i32;
foo::using(&mut local, stuff);

assert_eq!(local, 42);

stuff(); // doesn't do anything.
}

#[test]
fn unwind_recursive() {
use std::panic;

environmental!(items: Vec<u8>);

let panicked = panic::catch_unwind(|| {
let mut local_outer = vec![1, 2, 3];

items::using(&mut local_outer, || {
let mut local_inner = vec![4, 5, 6];
items::using(&mut local_inner, || {
panic!("are you unsafe?");
})
});
}).is_err();

assert!(panicked);

let mut was_cleared = true;
items::with(|_items| was_cleared = false);

assert!(was_cleared);
}
}
1 change: 1 addition & 0 deletions executor/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ serde = "1.0"
serde_derive = "1.0"
parity-wasm = "0.15.0"
byteorder = "1.1"
rustc-hex = "1.0.0"

[dev-dependencies]
assert_matches = "1.1"
1 change: 1 addition & 0 deletions executor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ extern crate polkadot_state_machine as state_machine;
extern crate serde;
extern crate parity_wasm;
extern crate byteorder;
extern crate rustc_hex;

#[macro_use]
extern crate error_chain;
Expand Down
Loading