Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Validation #151

Merged
merged 117 commits into from
Jun 7, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
117 commits
Select commit Hold shift + click to select a range
e132d1e
Change nightly version.
JakeOShannessy May 22, 2019
82bc64a
Add batch equivalent to build.sh
JakeOShannessy May 22, 2019
6c3cfbd
Update windows build command
JakeOShannessy May 24, 2019
cc53baa
Rough validation testing
JakeOShannessy May 24, 2019
1afedc3
Fix contract name
JakeOShannessy May 24, 2019
a560d29
Add cap9-build to link in sycalls
JakeOShannessy May 24, 2019
9741a42
Validate syscalls.
JakeOShannessy May 24, 2019
370430f
Functioning syscall linking and validation (albeit very messy)
JakeOShannessy May 25, 2019
2fae6bc
Change toolchain version
JakeOShannessy May 25, 2019
b6fd2c6
Merge branch 'master' into validation
JakeOShannessy May 25, 2019
1303273
Use cross platform CWD.
JakeOShannessy May 25, 2019
06100ef
Use no_std in native validator
JakeOShannessy May 25, 2019
0e32e3f
Clean up cap9-build logging
JakeOShannessy May 25, 2019
0fa8a40
Add toolchain to native-validator
JakeOShannessy May 25, 2019
bb0c581
Move validation code into separate lib
JakeOShannessy May 25, 2019
131ca1f
Switch to HTTP transport for tests
JakeOShannessy May 25, 2019
60f03e2
Merge branch 'improve-tests' into validation
JakeOShannessy May 25, 2019
cc9e985
Experiment with circleci
JakeOShannessy May 26, 2019
cb1cb37
Remove SolC
JakeOShannessy May 26, 2019
9d034a6
Only build ewasm
JakeOShannessy May 26, 2019
53950f6
Change parity command
JakeOShannessy May 26, 2019
7c2589c
Fix directory
JakeOShannessy May 26, 2019
f8f1760
Build wasm-build 0.6.0
JakeOShannessy May 26, 2019
220ca5b
Fix parity url
JakeOShannessy May 26, 2019
d66f8ac
Fix directory to run parity
JakeOShannessy May 26, 2019
8d2f530
Fix location of cargo.lock
JakeOShannessy May 26, 2019
eac1199
Fix parity path
JakeOShannessy May 26, 2019
1cc2f6c
Don't need to kill database
JakeOShannessy May 26, 2019
fda726b
Fix Cargo.lock path
JakeOShannessy May 26, 2019
9accf6e
Remove reference to Cargo.lock, which is not commited
JakeOShannessy May 26, 2019
333f697
Merge branch 'circleci' into validation
JakeOShannessy May 26, 2019
b9762c8
Correct specification of dev dependencies
JakeOShannessy May 28, 2019
2ed4c67
Fix no_std build
JakeOShannessy May 28, 2019
660db71
Fix std build
JakeOShannessy May 28, 2019
9352d6c
Add get_code_size to the kernel
JakeOShannessy May 28, 2019
4c2c83f
Use custom parity node in CI
JakeOShannessy May 28, 2019
bac700d
Fix installation of parity
JakeOShannessy May 28, 2019
3a8bd54
circleci: install cmake
JakeOShannessy May 28, 2019
fd6594a
circleci: use the right package manager
JakeOShannessy May 28, 2019
797ab2c
circleci: needed privileges
JakeOShannessy May 28, 2019
6847610
circleci: add more dependencies
JakeOShannessy May 28, 2019
cc94870
circleci: remove gflags
JakeOShannessy May 28, 2019
6405150
circleci: try different gflags package name
JakeOShannessy May 28, 2019
31f38b9
circleci: add perl and yasm
JakeOShannessy May 29, 2019
762edeb
circleci: see if we can use parity's image
JakeOShannessy May 29, 2019
09ac0bf
circleci: remove sudo
JakeOShannessy May 29, 2019
7f8dcdf
circleci: remove install line
JakeOShannessy May 29, 2019
8dcc9b3
circleci: try building parity's branch
JakeOShannessy May 29, 2019
5b4b72a
Copy example from parity's docker image
JakeOShannessy May 29, 2019
6f85428
circleci: actually clone parity
JakeOShannessy May 29, 2019
d9eded9
circleci: switch to stable parity
JakeOShannessy May 29, 2019
3d09fef
circleci: build syn first
JakeOShannessy May 29, 2019
c076db6
circleci: build syn from git
JakeOShannessy May 29, 2019
c981f44
circleci: dev build
JakeOShannessy May 29, 2019
774bfc8
circleci: build 1 package at a time
JakeOShannessy May 29, 2019
df48168
circleci: save cache after parity build
JakeOShannessy May 29, 2019
4000436
Revert "circleci: save cache after parity build"
JakeOShannessy May 29, 2019
e94c635
circleci: save cache after parity build
JakeOShannessy May 29, 2019
cba64d0
circleci: checkout code
JakeOShannessy May 29, 2019
5b110c2
circleci: restore cache
JakeOShannessy May 29, 2019
dc8f074
circleci: cache parity builds
JakeOShannessy May 29, 2019
e2bfc98
circleci: version bump deps
JakeOShannessy May 29, 2019
1c59ace
circleci: install parity stage
JakeOShannessy May 29, 2019
6bc0dc7
circleci: don't update rust
JakeOShannessy May 29, 2019
1c1a78c
circleci: set default toolchain
JakeOShannessy May 29, 2019
56e7099
circleci: reorder rustup
JakeOShannessy May 29, 2019
97f4bad
circleci: check for the existence of cargo
JakeOShannessy May 29, 2019
126bc5e
circleci: only install not build then install
JakeOShannessy May 29, 2019
70d7eb3
circleci: install this package
JakeOShannessy May 29, 2019
2b467b9
circleci: formatting
JakeOShannessy May 29, 2019
dbaa2fc
Don't update rust
JakeOShannessy May 29, 2019
d0eaf0b
circleci: cache rustup
JakeOShannessy May 29, 2019
fd70278
circleci: update PATH
JakeOShannessy May 29, 2019
55a95d7
circleci: checkout code
JakeOShannessy May 29, 2019
82405c6
circleci: fix .profile
JakeOShannessy May 29, 2019
8f5464c
circleci: force overwrite of parity node
JakeOShannessy May 29, 2019
93d9c7e
circleci: wrong line
JakeOShannessy May 29, 2019
b726332
circleci: add log line
JakeOShannessy May 29, 2019
e0aa815
circleci: more log lines
JakeOShannessy May 29, 2019
d3e3883
circleci: fix cache path
JakeOShannessy May 29, 2019
52028d1
circleci: properly namespace directories
JakeOShannessy May 29, 2019
e430223
circleci: fix yaml syntax error
JakeOShannessy May 29, 2019
8e8c06c
circleci: install nodejs
JakeOShannessy May 29, 2019
55685c4
circleci: add repo for nodejs
JakeOShannessy May 29, 2019
02e0e0e
circleci: add missing -y
JakeOShannessy May 29, 2019
596e964
circleci: install newer version of node
JakeOShannessy May 29, 2019
6109798
circleci: use .xz
JakeOShannessy May 29, 2019
72616dd
circleci: switch parity to master
JakeOShannessy May 29, 2019
500af4d
Build custom parity as part of ci (#152)
JakeOShannessy May 29, 2019
13bca73
validation: update whitelist and reorder to match parity.
JakeOShannessy Jun 4, 2019
f52ad3d
validation: add EXTCODECOPY and simple test
JakeOShannessy Jun 4, 2019
cd61a76
Validation merge (#154)
JakeOShannessy Jun 4, 2019
68698b8
Merge branch 'validation' of github.com:Daolab/beakeros into validation
JakeOShannessy Jun 4, 2019
e60b0ba
cap9-build: increase the amount of available memory in kernel
JakeOShannessy Jun 5, 2019
6671041
kernel: link in basic validation code for testing
JakeOShannessy Jun 5, 2019
26f8cc1
example_contact: expand
JakeOShannessy Jun 5, 2019
1c31300
cap9-build: properly pass the number of memory pages
JakeOShannessy Jun 5, 2019
5b811e9
kernel: LTO needs to be turned off for mem access bug workaround
JakeOShannessy Jun 5, 2019
72ddabe
kernel: unlock more tests
JakeOShannessy Jun 5, 2019
e1839e3
kernel: switch to git version of parity-wasm
JakeOShannessy Jun 5, 2019
1a2015b
kernel: use wasm module type exposed by validator
JakeOShannessy Jun 5, 2019
a85bbdb
kernel: set number of memory pages to 3
JakeOShannessy Jun 5, 2019
097212d
kernel: panic on inability to parse wasm
JakeOShannessy Jun 5, 2019
f912c3d
kernel: test simple procedure contract
JakeOShannessy Jun 5, 2019
2f83b1c
Switch to manual parsing for validation (#157)
JakeOShannessy Jun 6, 2019
1c04ca2
remove and gitignore build files
JakeOShannessy Jun 7, 2019
e720b14
validation: rustfmt and add tests
JakeOShannessy Jun 7, 2019
815adb5
wasm-parse: refactor
JakeOShannessy Jun 7, 2019
460fa07
wasm-parser: docs
JakeOShannessy Jun 7, 2019
f7e80ba
validation: forbid indirect calls
JakeOShannessy Jun 7, 2019
1497fd7
validation: correct invalidation of bad dcall
JakeOShannessy Jun 7, 2019
e9fb41f
wasm-parser: minor cleanup
JakeOShannessy Jun 7, 2019
dbcce4f
Merge branch 'master' into validation
JakeOShannessy Jun 7, 2019
feb077a
kernel: skip unimplemented test
JakeOShannessy Jun 7, 2019
39dc39c
wasm-parser: check for varuint32 issues
JakeOShannessy Jun 7, 2019
403dc91
wasm-parser: additional comments
JakeOShannessy Jun 7, 2019
597a281
whitespace
JakeOShannessy Jun 7, 2019
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
169 changes: 135 additions & 34 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -1,44 +1,145 @@
# Javascript Node CircleCI 2.0 configuration file
#
# Check https://circleci.com/docs/2.0/language-javascript/ for more details
#
version: 2
jobs:
build:
docker:
# specify the version you desire here
- image: circleci/node:9

# Specify service dependencies here if necessary
# CircleCI maintains a library of pre-built images
# documented at https://circleci.com/docs/2.0/circleci-images/
# - image: circleci/mongo:3.4.4
# build-evm:
# docker:
# # specify the version you desire here
# - image: circleci/node:9

working_directory: ~/repo
# # Specify service dependencies here if necessary
# # CircleCI maintains a library of pre-built images
# # documented at https://circleci.com/docs/2.0/circleci-images/
# # - image: circleci/mongo:3.4.4

steps:
- checkout
# working_directory: ~/repo

# Download and cache dependencies
- restore_cache:
keys:
- v1-dependencies-{{ checksum "evm1/package.json" }}
# fallback to using the latest cache if no exact match is found
- v1-dependencies-
# steps:
# - checkout

# # Download and cache dependencies
# - restore_cache:
# keys:
# - v1-dependencies-{{ checksum "evm1/package.json" }}
# # fallback to using the latest cache if no exact match is found
# - v1-dependencies-

# - run: cd evm1 && npm install
# - run: cd evm1 && chmod +x ./scripts/test.sh

- run: cd evm1 && npm install
- run: cd evm1 && chmod +x ./scripts/test.sh
# - save_cache:
# paths:
# - evm1/node_modules
# key: v1-dependencies-{{ checksum "evm1/package.json" }}

# # run tests!
# - run:
# name: Running Local EVM Instance
# command: ./evm1/node_modules/.bin/ganache-cli
# background: true
# - run: cd evm1 && ./node_modules/.bin/truffle test
build:
docker:
- image: centos:latest
working_directory: /tmp/my-project
steps:
- restore_cache:
keys:
- deps7-{{ .Branch }}-{{ .Revision }}
# - deps7-{{ .Branch }}-cargo-{{ checksum "kernel-ewasm/Cargo.lock" }}
- deps7-{{ .Branch }}-
- deps7-
- run:
name: Install native build prequisites
command: |
yum -y update
yum install -y systemd-devel git make gcc-c++ gcc file binutils
curl -L "https://cmake.org/files/v3.12/cmake-3.12.0-Linux-x86_64.tar.gz" -o cmake.tar.gz
tar -xzf cmake.tar.gz
cp -r cmake-3.12.0-Linux-x86_64/* /usr/
echo "PATH=/root/.cargo/bin:$PATH" >> ~/.profile
# only update cargo if it is not installed
if [ ! -d /root/.rustup ]
then
echo "Installing rustup"
curl https://sh.rustup.rs -sSf | sh -s -- -y
. ~/.profile
rustup default stable
else
echo "rustup already installed"
. ~/.profile
fi
RUST_BACKTRACE=1
rustc -vV
cargo -V
gcc -v
g++ -v
cmake --version
curl -L https://nodejs.org/dist/v12.3.1/node-v12.3.1-linux-x64.tar.xz -o node.tar.xz
tar -xJf node.tar.xz
cp -r node-v12.3.1-linux-x64/* /usr/
- run:
name: Install Parity
command: |
. ~/.profile
cd ..
# If the parity-ethereum directory does not exist, clone it
pwd
ls
if [ ! -d parity-ethereum ]
then
echo "Parity not installed, cloning..."
git clone https://github.com/Daohub-io/parity-ethereum.git
fi
cd parity-ethereum
git fetch --all
git checkout master
# cargo build -j 1
# cargo build --verbose --release --features final
# strip target/debug/parity
# file target/debug/parity
if parity --version; then
echo "Parity node installed"
else
cargo install --bin parity -j 1 --path . --bin parity parity-ethereum
fi
- save_cache:
key: deps7-{{ .Branch }}-cargo #-{{ checksum "kernel-ewasm/Cargo.lock" }}
paths:
- evm1/node_modules
key: v1-dependencies-{{ checksum "evm1/package.json" }}

# run tests!
- run:
name: Running Local EVM Instance
command: ./evm1/node_modules/.bin/ganache-cli
- "~/.cargo"
- "~/.rustup"
- /tmp/parity-ethereum
- checkout:
path: cap9
- run:
name: Get Submodules
command: |
cd cap9
git submodule update --init
- run:
name: Start local Ethereum network
command: |
. ~/.profile
cd cap9
cd kernel-ewasm
# we need to run parity once to set up the accounts and keys
# this only needs to be active for a few seconds (hence timeout)
# timeout 5 parity --config dev || true
# We then run parity properly, now unlocking the previously setup
# account
parity --config dev --chain ./wasm-dev-chain.json --jsonrpc-apis=all --ws-apis=all --reseal-min-period 0 --gasprice 0
background: true
- run: cd evm1 && ./node_modules/.bin/truffle test


- run:
name: Wait for Parity startup
command: sleep 10
- run:
name: Build Rust Component
command: |
. ~/.profile
cd cap9
cd kernel-ewasm && ./build.sh
- run:
name: Test Rust Component
command: |
. ~/.profile
cd cap9
cd kernel-ewasm && npm install
npm run test
1 change: 1 addition & 0 deletions cap9-build/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
target
10 changes: 10 additions & 0 deletions cap9-build/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[package]
name = "cap9-build"
version = "0.1.0"
authors = ["Jake O'Shannessy <joshannessy@gmail.com>"]
edition = "2018"

[dependencies]
parity-wasm = "0.31"
pwasm-utils = "0.7.0"
clap = "~2.32.0"
192 changes: 192 additions & 0 deletions cap9-build/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
extern crate parity_wasm;
extern crate pwasm_utils;

use parity_wasm::elements::{Module,MemoryType};
use clap::{Arg, App, SubCommand, ArgMatches};
use parity_wasm::elements::{Instructions, Instruction};

fn main() {
let matches = App::new("cap9-build")
.version("0.2.0")
.author("Cap9 <info@daohub.io>")
.about("A command-line interface for linking Cap9 procedures.")
.subcommand(SubCommand::with_name("build-proc")
.about("Convert a regular contract into a cap9 procedure.")
.arg(Arg::with_name("INPUT-FILE")
.required(true)
.help("input file"))
.arg(Arg::with_name("OUTPUT-FILE")
.required(true)
.help("output file")))
.subcommand(SubCommand::with_name("set-mem")
.about("Set the number of memory pages in a procedure.")
.arg(Arg::with_name("INPUT-FILE")
.required(true)
.help("input file"))
.arg(Arg::with_name("OUTPUT-FILE")
.required(true)
.help("output file"))
.arg(Arg::with_name("pages")
.short("p")
.long("pages")
.value_name("PAGES")
.required(true)
.help("Number of pages to set the memory to")))
.get_matches();

match matches.subcommand() {
("build-proc", Some(opts)) => {
let input_path = opts.value_of("INPUT-FILE").expect("input file is required");
let output_path = opts.value_of("OUTPUT-FILE").expect("output path is required");

let module = parity_wasm::deserialize_file(input_path).expect("parsing of input failed");
let new_module = contract_build(module);
parity_wasm::serialize_to_file(output_path, new_module).expect("serialising to output failed");
},
("set-mem", Some(opts)) => {
let input_path = opts.value_of("INPUT-FILE").expect("input file is required");
let output_path = opts.value_of("OUTPUT-FILE").expect("output path is required");
let mem_pages = opts.value_of("pages").expect("number of memory pages is required");

let module = parity_wasm::deserialize_file(input_path).expect("parsing of input failed");
let new_module = set_mem(module, mem_pages.parse().expect("expected number for number of pages"));
parity_wasm::serialize_to_file(output_path, new_module).expect("serialising to output failed");
},
_ => panic!("unknown subcommand")
}
}


/// Perform the operations necessary for cap9 procedures.
fn contract_build(module: Module) -> Module {

// TODO: we need to make sure these values never change between now and when
// we use them. In the current set up they will not, but it is fragile,
// there are changes that could be introduced which would change this.
let syscall_instructions_res = get_syscall_instructions(&module);

// TODO: what is the index of this newly added function?
let mut new_module_builder = parity_wasm::builder::from_module(module);
// Add the syscall function, if applicable.
let mut new_module = if let Ok(syscall_instructions) = syscall_instructions_res {
new_module_builder
.function()
.signature()
.with_param(parity_wasm::elements::ValueType::I32)
.with_param(parity_wasm::elements::ValueType::I32)
.with_param(parity_wasm::elements::ValueType::I32)
.with_param(parity_wasm::elements::ValueType::I32)
.with_return_type(Some(parity_wasm::elements::ValueType::I32))
.build()
.body()
.with_instructions(syscall_instructions)
.build()
.build()
.build()
} else {
new_module_builder.build()
};

// TODO: robustly determine the function index of the function we just
// added. I think at this point it's simply the last funciton added, thereby
// functions_space - 1, but this is not guaranteed anywhere.
let added_syscall_index = new_module.functions_space() - 1;

// If we find cap9_syscall_low as an import, we need to replace all
// references to it with a reference to this newly added function, and
// remove the import. Once we replace the internal references and run optimize, it will be removed anyway.
let cap9_syscall_low_index = find_import(&new_module, "env", "cap9_syscall_low");
match cap9_syscall_low_index {
None => (),
Some(syscall_index) => {
// Search though the code of each function, if we encounter a
// Call(syscall_index), replace it with Call(added_syscall_index).
// TODO: investigate the use of CallIndirect
for f in new_module.code_section_mut().unwrap().bodies_mut().iter_mut() {
for i in 0..f.code().elements().len() {
let instruction = &f.code().elements()[i];
if instruction == &Instruction::Call(syscall_index) {
f.code_mut().elements_mut()[i] = Instruction::Call(added_syscall_index as u32);
}
}
}
}
}

// Next we want to delete dummy_syscall if it exists. First we find it among
// the exports (if it doesn't exist we don't need to do anything). We take
// the reference of the export (i.e. the function it exports) and delete
// both that function and the export. One way to do this would be to delete
// the export and run the parity's optimizer again.
// 1. Get the index of the export
if let Some(dummy_syscall_export_index) = find_export(&new_module, "dummy_syscall") {
// println!("dummy_syscall_export_index: {}", dummy_syscall_export_index);
// 2. Delete the export
new_module.export_section_mut().unwrap().entries_mut().remove(dummy_syscall_export_index as usize);
}
// 3. At this stage the dummy_syscall function still exists internally. We
// can't use the same remove procedure without screwing up the internal
// references, so we will just run the parity optmizer again for now to
// let it deal with that.
pwasm_utils::optimize(&mut new_module, vec!["call","deploy"]).unwrap();
new_module
}

fn set_mem(mut module: Module, num_pages: u32) -> Module {
// We want to find the single memory section, and change it from its current
// value to the one we've requested.
let mut mem_entry: &mut Vec<MemoryType> = module.memory_section_mut().unwrap().entries_mut();
mem_entry[0] = parity_wasm::elements::MemoryType::new(num_pages,None);
module
}

// Find the function index of an import
fn find_import(module: &Module, mod_name: &str, field_name: &str) -> Option<u32> {
let imports = module.import_section().unwrap().entries();
for (i,import) in imports.iter().enumerate() {
if import.module() == mod_name && import.field() == field_name {
return Some(i as u32);
}
}
return None;
}

// Find the function index of an export
fn find_export(module: &Module, field_name: &str) -> Option<u32> {
let exports = module.export_section().unwrap().entries();
for (i,export) in exports.iter().enumerate() {
if export.field() == field_name {
return Some(i as u32);
}
}
return None;
}

enum SysCallError {
NoDCall,
NoGasLeft,
NoSender,
}

fn get_syscall_instructions(module: &Module) -> Result<Instructions,SysCallError> {
// If any of these three environments are not pulled in from the
// environment, we cannot have syscalls.
let dcall_index = find_import(module, "env", "dcall").ok_or(SysCallError::NoDCall)?;
let gasleft_index = find_import(module, "env", "gasleft").ok_or(SysCallError::NoGasLeft)?;
let sender_index = find_import(module, "env", "sender").ok_or(SysCallError::NoSender)?;
let syscall_instructions = parity_wasm::elements::Instructions::new(vec![
// Call gas
Instruction::Call(gasleft_index),
// Call sender
Instruction::Call(sender_index),
Instruction::GetLocal(0),
Instruction::GetLocal(1),
Instruction::GetLocal(2),
Instruction::GetLocal(3),
// Do the delegate call
Instruction::Call(dcall_index),
// End function
Instruction::End,
]);
Ok(syscall_instructions)
}
5 changes: 4 additions & 1 deletion kernel-ewasm/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,7 @@ node_modules

#CARGO
target
**/*.rs.bk
**/*.rs.bk

#Built Contracts
build/
Loading