mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-13 02:21:14 +00:00
Repot and introduce keccak-256 external.
This commit is contained in:
Generated
+3
@@ -687,8 +687,10 @@ dependencies = [
|
||||
"polkadot-primitives 0.1.0",
|
||||
"polkadot-serializer 0.1.0",
|
||||
"polkadot-state-machine 0.1.0",
|
||||
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -841,6 +843,7 @@ dependencies = [
|
||||
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parking_lot 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"polkadot-state-machine 0.1.0",
|
||||
"tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
@@ -12,6 +12,8 @@ serde = "1.0"
|
||||
serde_derive = "1.0"
|
||||
parity-wasm = "0.15.0"
|
||||
byteorder = "1.1"
|
||||
tiny-keccak = "1.3"
|
||||
rustc-hex = "1.0.0"
|
||||
|
||||
[dev-dependencies]
|
||||
assert_matches = "1.1"
|
||||
|
||||
@@ -33,6 +33,8 @@ extern crate polkadot_state_machine as state_machine;
|
||||
extern crate serde;
|
||||
extern crate parity_wasm;
|
||||
extern crate byteorder;
|
||||
extern crate tiny_keccak;
|
||||
extern crate rustc_hex;
|
||||
|
||||
#[macro_use]
|
||||
extern crate error_chain;
|
||||
|
||||
@@ -26,6 +26,7 @@ use state_machine::{Externalities, CodeExecutor};
|
||||
use error::{Error, ErrorKind, Result};
|
||||
use wasm_utils::{MemoryInstance, UserDefinedElements,
|
||||
AddModuleWithoutFullDependentInstance};
|
||||
use tiny_keccak;
|
||||
|
||||
struct Heap {
|
||||
end: u32,
|
||||
@@ -138,6 +139,15 @@ impl_function_executor!(this: FunctionExecutor<'e, E>,
|
||||
},
|
||||
ext_chain_id() -> u64 => {
|
||||
this.ext.chain_id()
|
||||
},
|
||||
ext_keccak256(data: *const u8, len: u32, out: *mut u8) => {
|
||||
let result =
|
||||
if let Ok(value) = this.memory.get(data, len as usize) {
|
||||
tiny_keccak::keccak256(&value)
|
||||
} else {
|
||||
[0; 32]
|
||||
};
|
||||
let _ = this.memory.set(out, &result);
|
||||
}
|
||||
=> <'e, E: Externalities + 'e>
|
||||
);
|
||||
@@ -193,6 +203,7 @@ impl CodeExecutor for WasmExecutor {
|
||||
mod tests {
|
||||
|
||||
use super::*;
|
||||
use rustc_hex::FromHex;
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
struct TestExternalities {
|
||||
@@ -213,50 +224,34 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_pass_externalities_at_call() {
|
||||
fn storage_should_work() {
|
||||
let mut ext = TestExternalities::default();
|
||||
ext.set_storage(b"\0code".to_vec(), b"The code".to_vec());
|
||||
ext.set_storage(b"foo".to_vec(), b"bar".to_vec());
|
||||
let test_code = include_bytes!("../../wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm");
|
||||
|
||||
let program = ProgramInstance::new().unwrap();
|
||||
|
||||
let test_module = include_bytes!("../../wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm");
|
||||
let module = deserialize_buffer(test_module.to_vec()).expect("Failed to load module");
|
||||
let module = program.add_module_by_sigs("test", module, map!["env" => FunctionExecutor::<TestExternalities>::SIGNATURES]).expect("Failed to initialize module");
|
||||
|
||||
let output = {
|
||||
let memory = module.memory(ItemIndex::Internal(0)).unwrap();
|
||||
let mut fec = FunctionExecutor::new(&memory, &mut ext);
|
||||
|
||||
let data = b"Hello world";
|
||||
let size = data.len() as u32;
|
||||
let offset = fec.heap.allocate(size);
|
||||
memory.set(offset, data).unwrap();
|
||||
|
||||
let returned = program
|
||||
.params_with_external("env", &mut fec)
|
||||
.map(|p| p
|
||||
.add_argument(I32(offset as i32))
|
||||
.add_argument(I32(size as i32)))
|
||||
.and_then(|p| module.execute_export("test_data_in", p))
|
||||
.map_err(|_| -> Error { ErrorKind::Runtime.into() }).expect("function should be callable");
|
||||
|
||||
if let Some(I64(r)) = returned {
|
||||
println!("returned {:?} ({:?}, {:?})", r, r as u32, (r >> 32) as u32 as usize);
|
||||
memory.get(r as u32, (r >> 32) as u32 as usize).expect("memory address should be reasonable.")
|
||||
} else {
|
||||
panic!("bad return value, not u64");
|
||||
}
|
||||
};
|
||||
let output = WasmExecutor.call(&mut ext, &test_code[..], "test_data_in", &CallData(b"Hello world".to_vec())).unwrap();
|
||||
|
||||
assert_eq!(output, b"all ok!".to_vec());
|
||||
|
||||
let expected: HashMap<_, _> = map![
|
||||
b"\0code".to_vec() => b"Hello world".to_vec(),
|
||||
b"input".to_vec() => b"Hello world".to_vec(),
|
||||
b"code".to_vec() => b"The code".to_vec(),
|
||||
b"\0authority_count".to_vec() => vec![1],
|
||||
b"\0authority".to_vec() => b"Hello world".to_vec()
|
||||
b"foo".to_vec() => b"bar".to_vec(),
|
||||
b"baz".to_vec() => b"bar".to_vec()
|
||||
];
|
||||
assert_eq!(expected, ext.storage);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn keccak256_should_work() {
|
||||
let mut ext = TestExternalities::default();
|
||||
let test_code = include_bytes!("../../wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm");
|
||||
assert_eq!(
|
||||
WasmExecutor.call(&mut ext, &test_code[..], "test_keccak256", &CallData(b"".to_vec())).unwrap(),
|
||||
FromHex::from_hex("c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470").unwrap()
|
||||
);
|
||||
assert_eq!(
|
||||
WasmExecutor.call(&mut ext, &test_code[..], "test_keccak256", &CallData(b"Hello world!".to_vec())).unwrap(),
|
||||
FromHex::from_hex("ecd0e108a98e192af1d2c25055f4e3bed784b5c877204e73219a5203251feaab").unwrap()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,3 +11,4 @@ lazy_static = "1.0.0"
|
||||
parking_lot = "0.5"
|
||||
polkadot-state-machine = { path = "../../state_machine" , version = "0.1" }
|
||||
environmental = { path = "../../environmental", version = "0.1.0" }
|
||||
tiny-keccak = "1.3"
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#[macro_use]
|
||||
extern crate environmental;
|
||||
extern crate polkadot_state_machine;
|
||||
extern crate tiny_keccak;
|
||||
|
||||
pub use std::vec::Vec;
|
||||
pub use std::rc::Rc;
|
||||
@@ -75,6 +76,9 @@ pub fn chain_id() -> u64 {
|
||||
).unwrap_or(0)
|
||||
}
|
||||
|
||||
/// Conduct a Keccak-256 hash of the given data.
|
||||
pub use tiny_keccak::keccak256;
|
||||
|
||||
/// Execute the given closure with global function available whose functionality routes into the
|
||||
/// externalities `ext`. Forwards the value that the closure returns.
|
||||
pub fn with_externalities<R, F: FnOnce() -> R>(ext: &mut Externalities<Error=NoError>, f: F) -> R {
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
pub mod endiansensitive;
|
||||
pub mod streamreader;
|
||||
pub mod joiner;
|
||||
pub mod slicable;
|
||||
pub mod keyedvec;
|
||||
@@ -4,20 +4,14 @@
|
||||
#[macro_use]
|
||||
extern crate runtime_support;
|
||||
|
||||
mod codec;
|
||||
mod support;
|
||||
pub use support::{endiansensitive, streamreader, joiner, slicable, primitives, keyedvec, function,
|
||||
environment, storage};
|
||||
mod runtime;
|
||||
pub use codec::{endiansensitive, streamreader, joiner, slicable, keyedvec};
|
||||
pub use support::{primitives, function, environment, storage};
|
||||
#[cfg(test)]
|
||||
pub use support::testing;
|
||||
|
||||
#[allow(unused)]
|
||||
mod system;
|
||||
#[allow(unused)]
|
||||
mod consensus;
|
||||
#[allow(unused)]
|
||||
mod staking;
|
||||
#[allow(unused)]
|
||||
mod timestamp;
|
||||
#[allow(unused_imports)] // TODO: remove in due course
|
||||
|
||||
use runtime_support::Vec;
|
||||
use slicable::Slicable;
|
||||
@@ -29,11 +23,11 @@ use primitives::{Block, Transaction};
|
||||
// - ECDSA-recover (or some better sig scheme)
|
||||
|
||||
pub fn execute_block(input: Vec<u8>) -> Vec<u8> {
|
||||
system::execute_block(Block::from_slice(&input).unwrap())
|
||||
runtime::system::execute_block(Block::from_slice(&input).unwrap())
|
||||
}
|
||||
|
||||
pub fn execute_transaction(input: Vec<u8>) -> Vec<u8> {
|
||||
system::execute_transaction(&Transaction::from_slice(&input).unwrap())
|
||||
runtime::system::execute_transaction(&Transaction::from_slice(&input).unwrap())
|
||||
}
|
||||
|
||||
impl_stubs!(execute_block, execute_transaction);
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
#[allow(unused)]
|
||||
pub mod system;
|
||||
#[allow(unused)]
|
||||
pub mod consensus;
|
||||
#[allow(unused)]
|
||||
pub mod staking;
|
||||
#[allow(unused)]
|
||||
pub mod timestamp;
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
use keyedvec::KeyedVec;
|
||||
use storage::{Storage, storage_into};
|
||||
use primitives::{BlockNumber, Balance, AccountID};
|
||||
use consensus;
|
||||
use runtime::consensus;
|
||||
|
||||
/// The length of a staking era in blocks.
|
||||
pub fn era_length() -> BlockNumber {
|
||||
@@ -68,7 +68,7 @@ mod tests {
|
||||
use runtime_support::with_externalities;
|
||||
use testing::TestExternalities;
|
||||
use primitives::{AccountID};
|
||||
use staking;
|
||||
use runtime::staking;
|
||||
|
||||
macro_rules! map {
|
||||
($( $name:expr => $value:expr ),*) => (
|
||||
+2
-3
@@ -1,8 +1,8 @@
|
||||
use primitives::{Block, BlockNumber, Hash, Transaction};
|
||||
use runtime_support::{Vec, swap};
|
||||
use environment::with_env;
|
||||
use staking;
|
||||
use runtime_support;
|
||||
use runtime::staking;
|
||||
|
||||
/// The current block number being processed. Set by `execute_block`.
|
||||
pub fn block_number() -> BlockNumber {
|
||||
@@ -79,8 +79,7 @@ mod tests {
|
||||
use std::collections::HashMap;
|
||||
use runtime_support::{NoError, with_externalities, Externalities};
|
||||
use primitives::{AccountID, Transaction};
|
||||
use system;
|
||||
use staking;
|
||||
use runtime::{system, staking};
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
struct TestExternalities {
|
||||
@@ -1,5 +1,4 @@
|
||||
use staking;
|
||||
use consensus;
|
||||
use runtime::{staking, consensus};
|
||||
use primitives::AccountID;
|
||||
use streamreader::StreamReader;
|
||||
|
||||
|
||||
@@ -1,9 +1,4 @@
|
||||
pub mod endiansensitive;
|
||||
pub mod streamreader;
|
||||
pub mod joiner;
|
||||
pub mod slicable;
|
||||
pub mod primitives;
|
||||
pub mod keyedvec;
|
||||
pub mod function;
|
||||
pub mod environment;
|
||||
pub mod storage;
|
||||
|
||||
@@ -29,6 +29,7 @@ extern "C" {
|
||||
fn ext_get_allocated_storage(key_data: *const u8, key_len: u32, written_out: *mut u32) -> *mut u8;
|
||||
fn ext_get_storage_into(key_data: *const u8, key_len: u32, value_data: *mut u8, value_len: u32) -> u32;
|
||||
fn ext_chain_id() -> u64;
|
||||
fn ext_keccak256(data: *const u8, len: u32, out: *mut u8);
|
||||
}
|
||||
|
||||
pub fn storage(key: &[u8]) -> Vec<u8> {
|
||||
@@ -78,6 +79,16 @@ pub fn chain_id() -> u64 {
|
||||
}
|
||||
}
|
||||
|
||||
/// Conduct a keccak256 hash.
|
||||
pub fn keccak256(data: &[u8]) -> [u8; 32] {
|
||||
unsafe {
|
||||
let mut result: [u8; 32] = uninitialized();
|
||||
// guaranteed to write into result.
|
||||
ext_keccak256(&data[0], data.len() as u32, &mut result[0]);
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Printable {
|
||||
fn print(self);
|
||||
}
|
||||
|
||||
BIN
Binary file not shown.
Binary file not shown.
@@ -8,72 +8,25 @@ use alloc::vec::Vec;
|
||||
|
||||
#[macro_use]
|
||||
extern crate runtime_support;
|
||||
use runtime_support::{set_storage, storage, print};
|
||||
use runtime_support::{set_storage, storage, print, keccak256};
|
||||
|
||||
pub fn code() -> Vec<u8> {
|
||||
storage(b"\0code")
|
||||
fn test_keccak256(input: Vec<u8>) -> Vec<u8> {
|
||||
keccak256(&input).to_vec()
|
||||
}
|
||||
|
||||
pub fn set_code(new: &[u8]) {
|
||||
set_storage(b"\0code", new)
|
||||
}
|
||||
|
||||
fn value_vec(mut value: usize, initial: Vec<u8>) -> Vec<u8> {
|
||||
let mut acc = initial;
|
||||
while value > 0 {
|
||||
acc.push(value as u8);
|
||||
value /= 256;
|
||||
}
|
||||
acc
|
||||
}
|
||||
|
||||
pub fn set_authority(index: usize, authority: &[u8]) {
|
||||
set_storage(&value_vec(index, b"\0authority".to_vec()), authority);
|
||||
}
|
||||
|
||||
pub fn authority(index: usize) -> Vec<u8> {
|
||||
storage(&value_vec(index, b"\0authority".to_vec()))
|
||||
}
|
||||
|
||||
pub fn set_authority_count(count: usize) {
|
||||
(count..authority_count()).for_each(|i| set_authority(i, &[]));
|
||||
set_storage(b"\0authority_count", &value_vec(count, Vec::new()));
|
||||
}
|
||||
|
||||
pub fn authority_count() -> usize {
|
||||
storage(b"\0authority_count").into_iter().rev().fold(0, |acc, i| (acc << 8) + (i as usize))
|
||||
}
|
||||
|
||||
pub fn authorities() -> Vec<Vec<u8>> {
|
||||
(0..authority_count()).into_iter().map(authority).collect()
|
||||
}
|
||||
|
||||
pub fn set_authorities(authorities: &[&[u8]]) {
|
||||
set_authority_count(authorities.len());
|
||||
authorities.iter().enumerate().for_each(|(v, i)| set_authority(v, i));
|
||||
}
|
||||
|
||||
impl_stubs!(test_data_in);
|
||||
fn test_data_in(input: Vec<u8>) -> Vec<u8> {
|
||||
print(b"set_storage" as &[u8]);
|
||||
set_storage(b"input", &input);
|
||||
|
||||
print(b"code" as &[u8]);
|
||||
set_storage(b"code", &code());
|
||||
|
||||
print(b"set_code" as &[u8]);
|
||||
set_code(&input);
|
||||
|
||||
print(b"storage" as &[u8]);
|
||||
let copy = storage(b"input");
|
||||
let foo = storage(b"foo");
|
||||
|
||||
print(b"authorities" as &[u8]);
|
||||
let mut v = authorities();
|
||||
v.push(copy);
|
||||
|
||||
print(b"set_authorities" as &[u8]);
|
||||
set_authorities(&v.iter().map(Vec::as_slice).collect::<Vec<_>>());
|
||||
print(b"set_storage" as &[u8]);
|
||||
set_storage(b"baz", &foo);
|
||||
|
||||
print(b"finished!" as &[u8]);
|
||||
b"all ok!".to_vec()
|
||||
}
|
||||
|
||||
|
||||
impl_stubs!(test_data_in, test_keccak256);
|
||||
|
||||
Reference in New Issue
Block a user