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 1 commit
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
a83059a
Completely rework dispatch mechanism into something modular.
gavofyork Mar 13, 2018
82a178d
Council vote tests.
gavofyork Mar 13, 2018
1d28d9a
Fix tests.
gavofyork Mar 13, 2018
69c88c3
whitespace.
gavofyork Mar 13, 2018
b12a708
Fix demo runtime tests.
gavofyork Mar 14, 2018
e48e86d
Merge branch 'gav-demo' into gav-dispatch
gavofyork Mar 14, 2018
8e3cc51
Fix up tests.
gavofyork Mar 14, 2018
53e2fdf
Merge branch 'gav-demo' into gav-dispatch
gavofyork Mar 14, 2018
27ecd6f
Merge branch 'master' into gav-dispatch
gavofyork Mar 14, 2018
5eca74a
Remove dead code.
gavofyork Mar 14, 2018
5d5f194
Initial util code for random beacon
gavofyork Mar 14, 2018
7cece3b
Merge branch 'master' into gav-dispatch
gavofyork Mar 14, 2018
8c2396d
Timestamp uses new storage API.
gavofyork Mar 14, 2018
6b6c240
Move over system module to new API.
gavofyork Mar 14, 2018
a79dab2
Much nicer storage API, moved over staking module.
gavofyork Mar 15, 2018
1fd6b3e
More refactoring.
gavofyork Mar 15, 2018
51b4a8c
Democracy uses new storage API.
gavofyork Mar 15, 2018
8ada9f7
Council uses new RPC.
gavofyork Mar 16, 2018
c4f5f42
Fix more tests.
gavofyork Mar 16, 2018
d11f5ca
Use match for Id
gavofyork Mar 16, 2018
53eb893
Merge branch 'gav-storage-revamp' into gav-random-beacon
gavofyork Mar 16, 2018
d228593
Generic mix.
gavofyork Mar 16, 2018
a90fbe3
Integrate random beacon
gavofyork Mar 16, 2018
d352727
Update binaries.
gavofyork Mar 16, 2018
19f7258
Fixes relating to with_ext removal.
gavofyork Mar 16, 2018
ff2fa3c
Remove dead code.
gavofyork Mar 16, 2018
c674963
Rework mixer into an iterator adaptor.
gavofyork Mar 17, 2018
c49d8a9
Merge branch 'master' into gav-random-beacon
gavofyork Mar 19, 2018
74a59b9
Link to paper.
gavofyork Mar 19, 2018
23ca1b2
Algorithm cleanups
gavofyork Mar 19, 2018
1bb150b
Merge and fix test.
gavofyork Mar 19, 2018
2e9fa09
Docs.
gavofyork Mar 19, 2018
e4c2b27
Fix typo.
gavofyork Mar 19, 2018
90dd1a5
rename
gavofyork Mar 19, 2018
f197714
Fix tests.
gavofyork Mar 19, 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
Prev Previous commit
Next Next commit
Integrate random beacon
  • Loading branch information
gavofyork committed Mar 16, 2018
commit a90fbe3346a2cdd03ab12a613bb50b35401c26c9
72 changes: 38 additions & 34 deletions demo/runtime/src/runtime/system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,25 +22,25 @@ use rstd::mem;
use runtime_io::{print, storage_root, enumerated_trie_root};
use codec::{KeyedVec, Slicable};
use runtime_support::{Hashable, storage, StorageValue, StorageMap};
use environment::with_env;
use demo_primitives::{AccountId, Hash, TxOrder, BlockNumber, Header, Log};
use block::Block;
use block::{self, Block};
use transaction::UncheckedTransaction;
use runtime::{staking, session};
use dispatch;
use safe_mix::mix_iter;

storage_items! {
pub Nonce: b"sys:non" => default map [ AccountId => TxOrder ];
pub BlockHashAt: b"sys:old" => required map [ BlockNumber => Hash ];
pub Nonce get(nonce): b"sys:non" => default map [ AccountId => TxOrder ];
pub BlockHashAt get(block_hash): b"sys:old" => required map [ BlockNumber => Hash ];
RandomSeed get(random_seed): b"sys:rnd" => required Hash;
// The current block number being processed. Set by `execute_block`.
Number get(block_number): b"sys:num" => required BlockNumber;
ParentHash get(parent_hash): b"sys:pha" => required Hash;
Digest: b"sys:dig" => default block::Digest;
}

pub const CODE: &'static[u8] = b":code";

/// The current block number being processed. Set by `execute_block`.
pub fn block_number() -> BlockNumber {
with_env(|e| e.block_number)
}

pub struct PrivPass;

impl_dispatch! {
Expand All @@ -62,16 +62,17 @@ pub mod internal {

/// Deposits a log and ensures it matches the blocks log data.
pub fn deposit_log(log: Log) {
with_env(|e| e.digest.logs.push(log));
let mut l = Digest::get();
l.logs.push(log);
Digest::put(l);
}

/// Actually execute all transitioning for `block`.
pub fn execute_block(mut block: Block) {
// populate environment from header.
with_env(|e| {
e.block_number = block.header.number;
e.parent_hash = block.header.parent_hash;
});
Number::put(block.header.number);
ParentHash::put(block.header.parent_hash);
RandomSeed::put(calculate_random());

// any initial checks
initial_checks(&block);
Expand All @@ -94,37 +95,31 @@ pub mod internal {
/// This doesn't attempt to validate anything regarding the block.
pub fn execute_transaction(utx: UncheckedTransaction, mut header: Header) -> Header {
// populate environment from header.
with_env(|e| {
e.block_number = header.number;
e.parent_hash = header.parent_hash;
mem::swap(&mut header.digest, &mut e.digest);
});
Number::put(header.number);
ParentHash::put(header.parent_hash);
Digest::put(&header.digest);
RandomSeed::put(calculate_random());

super::execute_transaction(utx);

with_env(|e| {
mem::swap(&mut header.digest, &mut e.digest);
});
header.digest = Digest::get();
header
}

/// Finalise the block - it is up the caller to ensure that all header fields are valid
/// except state-root.
pub fn finalise_block(mut header: Header) -> Header {
// populate environment from header.
with_env(|e| {
e.block_number = header.number;
e.parent_hash = header.parent_hash;
mem::swap(&mut header.digest, &mut e.digest);
});
Number::put(header.number);
ParentHash::put(header.parent_hash);
Digest::put(&header.digest);
RandomSeed::put(calculate_random());

staking::internal::check_new_era();
session::internal::check_rotate_session();

header.state_root = storage_root().into();
with_env(|e| {
mem::swap(&mut header.digest, &mut e.digest);
});
header.digest = Digest::get();

post_finalise(&header);

Expand Down Expand Up @@ -176,9 +171,12 @@ fn final_checks(block: &Block) {
let ref header = block.header;

// check digest
with_env(|e| {
assert!(header.digest == e.digest);
});
assert!(header.digest == Digest::get());

Number::kill();
ParentHash::kill();
RandomSeed::kill();
Digest::kill();

// check storage root.
let storage_root = storage_root().into();
Expand All @@ -192,6 +190,13 @@ fn post_finalise(header: &Header) {
BlockHashAt::insert(&header.number, &header.blake2_256().into());
}

fn calculate_random() -> Hash {
let c = block_number() - 1;
mix_iter((0..81)
.map(|i| if c >= i { block_hash(c - i) } else { Default::default() })
Copy link
Contributor

@rphmeier rphmeier Mar 20, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so for the first 81 blocks the random seed won't be random at all -- I wonder if it's better to use a filter_map so that the early randomness is much more manipulable but not dominated by zero hashes. In polkadot we should have an initial epoch shuffle which ends after randomness is well-seeded.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it'll still be a bit random. but sure, lower security. thankfully it doesn't really matter.

)
}

#[cfg(feature = "std")]
fn info_expect_equal_hash(given: &Hash, expected: &Hash) {
use primitives::hexdisplay::HexDisplay;
Expand Down Expand Up @@ -231,7 +236,6 @@ mod tests {
use runtime_support::StorageValue;
use codec::{Joiner, KeyedVec, Slicable};
use keyring::Keyring::*;
use environment::with_env;
use primitives::hexdisplay::HexDisplay;
use demo_primitives::{Header, Digest};
use transaction::{UncheckedTransaction, Transaction};
Expand Down
33 changes: 33 additions & 0 deletions demo/runtime/src/safe_mix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
//! Means of mixing a series of hashes to create a single secure hash.

use rstd::ops::{BitAnd, BitOr};
use rstd::cmp;

fn sub_mix<T>(seeds: &[T]) -> T where
T: BitAnd<Output = T> + BitOr<Output = T> + Copy
Expand All @@ -29,6 +30,8 @@ pub fn mix<T>(seeds: &[T]) -> Result<T, ()> where
T: BitAnd<Output = T> + BitOr<Output = T>,
T: Default + Copy
{
Ok(mix_iter(seeds.iter().cloned()))
/*
let max_depth = (0..12)
.scan(1, |a, _| { *a *= 3; Some(*a) })
.position(|v| seeds.len() == v)
Expand All @@ -52,8 +55,38 @@ pub fn mix<T>(seeds: &[T]) -> Result<T, ()> where
}
}
Ok(accum[max_depth][0])
*/
}

pub fn mix_iter<T, I>(seeds: I) -> T where
T: BitAnd<Output = T> + BitOr<Output = T>,
T: Default + Copy,
I: Iterator<Item = T>
{
let mut accum = [[T::default(); 3]; 13];
let mut max_depth = 0;
for (i, seed) in seeds.enumerate() {
accum[0][i % 3] = seed;
let mut index_at_depth = i;
for depth in 0..13 {
if index_at_depth % 3 != 2 {
break;
}
index_at_depth /= 3;

// end of the threesome at depth.
accum[depth + 1][index_at_depth % 3] = sub_mix(&accum[depth]);
max_depth = cmp::max(max_depth, depth + 1);
if max_depth == 12 {
break;
}
}
}
accum[max_depth][0]
}



#[cfg(test)]
mod tests {
use super::*;
Expand Down