forked from paritytech/substrate
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlib.rs
121 lines (106 loc) · 3.41 KB
/
lib.rs
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#![no_std]
#![feature(panic_handler)]
#![cfg_attr(feature = "strict", deny(warnings))]
#![feature(alloc)]
extern crate alloc;
use alloc::vec::Vec;
#[macro_use]
extern crate substrate_runtime_io as runtime_io;
extern crate substrate_runtime_sandbox as sandbox;
use runtime_io::{
set_storage, storage, clear_prefix, print, blake2_256,
twox_128, twox_256, ed25519_verify, enumerated_trie_root
};
impl_stubs!(
test_data_in NO_DECODE => |input| {
print("set_storage");
set_storage(b"input", input);
print("storage");
let foo = storage(b"foo").unwrap();
print("set_storage");
set_storage(b"baz", &foo);
print("finished!");
b"all ok!".to_vec()
},
test_clear_prefix NO_DECODE => |input| {
clear_prefix(input);
b"all ok!".to_vec()
},
test_empty_return NO_DECODE => |_| Vec::new(),
test_panic NO_DECODE => |_| panic!("test panic"),
test_conditional_panic NO_DECODE => |input: &[u8]| {
if input.len() > 0 {
panic!("test panic")
}
input.to_vec()
},
test_blake2_256 NO_DECODE => |input| blake2_256(input).to_vec(),
test_twox_256 NO_DECODE => |input| twox_256(input).to_vec(),
test_twox_128 NO_DECODE => |input| twox_128(input).to_vec(),
test_ed25519_verify NO_DECODE => |input: &[u8]| {
let mut pubkey = [0; 32];
let mut sig = [0; 64];
pubkey.copy_from_slice(&input[0..32]);
sig.copy_from_slice(&input[32..96]);
let msg = b"all ok!";
[ed25519_verify(&sig, &msg[..], &pubkey) as u8].to_vec()
},
test_enumerated_trie_root NO_DECODE => |_| {
enumerated_trie_root(&[&b"zero"[..], &b"one"[..], &b"two"[..]]).to_vec()
},
test_sandbox NO_DECODE => |code: &[u8]| {
let ok = execute_sandboxed(code, &[]).is_ok();
[ok as u8].to_vec()
},
test_sandbox_args NO_DECODE => |code: &[u8]| {
let ok = execute_sandboxed(
code,
&[
sandbox::TypedValue::I32(0x12345678),
sandbox::TypedValue::I64(0x1234567887654321),
]
).is_ok();
[ok as u8].to_vec()
},
test_sandbox_return_val NO_DECODE => |code: &[u8]| {
let result = execute_sandboxed(
code,
&[
sandbox::TypedValue::I32(0x1336),
]
);
let ok = if let Ok(sandbox::ReturnValue::Value(sandbox::TypedValue::I32(0x1337))) = result { true } else { false };
[ok as u8].to_vec()
}
);
fn execute_sandboxed(code: &[u8], args: &[sandbox::TypedValue]) -> Result<sandbox::ReturnValue, sandbox::HostError> {
struct State {
counter: u32,
}
fn env_assert(_e: &mut State, args: &[sandbox::TypedValue]) -> Result<sandbox::ReturnValue, sandbox::HostError> {
if args.len() != 1 {
return Err(sandbox::HostError);
}
let condition = args[0].as_i32().ok_or_else(|| sandbox::HostError)?;
if condition != 0 {
Ok(sandbox::ReturnValue::Unit)
} else {
Err(sandbox::HostError)
}
}
fn env_inc_counter(e: &mut State, args: &[sandbox::TypedValue]) -> Result<sandbox::ReturnValue, sandbox::HostError> {
if args.len() != 1 {
return Err(sandbox::HostError);
}
let inc_by = args[0].as_i32().ok_or_else(|| sandbox::HostError)?;
e.counter += inc_by as u32;
Ok(sandbox::ReturnValue::Value(sandbox::TypedValue::I32(e.counter as i32)))
}
let mut state = State { counter: 0 };
let mut env_builder = sandbox::EnvironmentDefinitionBuilder::new();
env_builder.add_host_func("env", "assert", env_assert);
env_builder.add_host_func("env", "inc_counter", env_inc_counter);
let mut instance = sandbox::Instance::new(code, &env_builder, &mut state)?;
let result = instance.invoke(b"call", args, &mut state);
result.map_err(|_| sandbox::HostError)
}