Skip to content

Commit 46e65b0

Browse files
committed
More templates
1 parent c2a9a9b commit 46e65b0

File tree

7 files changed

+150
-0
lines changed

7 files changed

+150
-0
lines changed

c-wrapper-crate/Cargo.toml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[package]
2+
name = "{{project-name}}"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
[dependencies]
7+
8+
[build-dependencies]
9+
cc = "1.0"

c-wrapper-crate/build.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
fn main() {
2+
println!("cargo:rerun-if-changed=c.c");
3+
4+
let top = match std::env::var("TOP") {
5+
Ok(top) => top,
6+
Err(_) => "../..".to_string(),
7+
};
8+
9+
let target_arch = std::env::var("CARGO_CFG_TARGET_ARCH").unwrap();
10+
if target_arch == "riscv64" {
11+
let mut build = cc::Build::new();
12+
assert!(
13+
build.get_compiler().is_like_clang(),
14+
"Clang must be used as the compiler!"
15+
);
16+
build
17+
.file("c.c")
18+
.static_flag(true)
19+
.include(format!("{}/deps/ckb-c-stdlib", top))
20+
.include(format!("{}/deps/ckb-c-stdlib/libc", top))
21+
.no_default_flags(true)
22+
.flag("--target=riscv64")
23+
.flag("-march=rv64imc_zba_zbb_zbc_zbs")
24+
.flag("-O3")
25+
.flag("-nostdinc")
26+
.flag("-nostdlib")
27+
.flag("-fvisibility=hidden")
28+
.flag("-fdata-sections")
29+
.flag("-ffunction-sections")
30+
.flag("-Wall")
31+
.flag("-Werror")
32+
.flag("-Wno-unused-parameter")
33+
.define("CKB_DECLARATION_ONLY", None)
34+
.compile("c-impl");
35+
}
36+
}

c-wrapper-crate/c.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
int bar() {
2+
return 42;
3+
}

c-wrapper-crate/src/lib.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#![cfg_attr(not(test), no_std)]
2+
3+
#[cfg(target_arch = "riscv64")]
4+
#[link(name = "c-impl", kind = "static")]
5+
extern "C" {
6+
fn bar() -> core::ffi::c_int;
7+
}
8+
9+
pub fn value() -> u32 {
10+
(unsafe { bar() }) as u32
11+
}

cargo-generate.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,7 @@
22
sub_templates = [
33
"contract",
44
"standalone-contract",
5+
"c-wrapper-crate",
6+
"x64-simulator-crate",
57
"workspace",
68
]

x64-simulator-crate/Cargo.toml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
[package]
2+
name = "{{project-name}}"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
[dependencies]
7+
ckb-std = "0.15.0"
8+
9+
# Supporting native tests powered by ckb-x64-simulator
10+
[target.'cfg(all(target_arch = "x86_64", unix))'.dependencies.ckb-std]
11+
version = "0.15.0"
12+
features = ["simulator"]
13+
14+
[target.'cfg(all(target_arch = "x86_64", unix))'.dev-dependencies]
15+
ckb-testtool = "0.10.1"
16+
rusty-fork = "0.3.0"
17+
rand = "0.8.5"
18+
serde_json = "1.0"
19+
tempfile = "3.9.0"

x64-simulator-crate/src/lib.rs

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
#![cfg_attr(not(test), no_std)]
2+
3+
pub fn foo() -> usize {
4+
ckb_std::high_level::load_witness(0, ckb_std::ckb_constants::Source::Input)
5+
.expect("load_witness")
6+
.len()
7+
}
8+
9+
// Here we provide a native runnable test sample. The test uses ckb-x64-simulator
10+
// to mock CKB syscalls.
11+
#[cfg(all(test, target_arch = "x86_64", unix))]
12+
mod tests {
13+
use super::*;
14+
use ckb_testtool::ckb_types::{core::TransactionBuilder, prelude::*};
15+
use ckb_testtool::context::Context;
16+
use rand::{rngs::StdRng, Rng, SeedableRng};
17+
use rusty_fork::rusty_fork_test;
18+
use std::io::Write;
19+
20+
// TODO: Right now ckb-x64-simulator has no way of resetting the
21+
// test transaction after initial setup. Hence we have to use this
22+
// circumvent way of testing. Later we would want to fix ckb-x64-simulator
23+
// so test data can be properly mutated, after that, we can switch
24+
// to proptest for testing here.
25+
rusty_fork_test! {
26+
#[test]
27+
fn test_any_data() {
28+
let seed: u64 = match std::env::var("SEED") {
29+
Ok(val) => str::parse(&val).expect("parsing number"),
30+
Err(_) => std::time::SystemTime::now()
31+
.duration_since(std::time::SystemTime::UNIX_EPOCH)
32+
.unwrap()
33+
.as_nanos() as u64,
34+
};
35+
println!("Seed: {}", seed);
36+
37+
let mut rng = StdRng::seed_from_u64(seed);
38+
let length = rng.gen_range(0..614400usize);
39+
let data = {
40+
let mut data = vec![0u8; length];
41+
rng.fill(&mut data[..]);
42+
data
43+
};
44+
let data_length = data.len();
45+
46+
let file = {
47+
// Build a tx using data as a cell
48+
let context = Context::default();
49+
let tx = TransactionBuilder::default()
50+
.witness(data.pack())
51+
.build();
52+
53+
let mock_tx = context.dump_tx(&tx).expect("dump tx");
54+
55+
// Keep the tx in a temporary file, then set the environment
56+
// variable for ckb-x64-simulator
57+
let json = serde_json::to_string_pretty(&mock_tx).expect("json");
58+
let mut file = tempfile::NamedTempFile::new().expect("tempfile");
59+
file.write_all(json.as_ref()).expect("write");
60+
file.flush().expect("flush");
61+
std::env::set_var("CKB_TX_FILE", file.path());
62+
file
63+
};
64+
65+
assert_eq!(foo(), data_length);
66+
67+
drop(file);
68+
}
69+
}
70+
}

0 commit comments

Comments
 (0)