Skip to content

Commit

Permalink
contracts: use cargo to build c-example
Browse files Browse the repository at this point in the history
This entails rewriting the `c-example` contract in rust, but without
using `piecrust-uplink`. This removes a dependency on `llvm` for build
time, significantly improving developer experience.
  • Loading branch information
Eduardo Leegwater Simões committed Dec 6, 2023
1 parent a8d4bba commit db9ac64
Show file tree
Hide file tree
Showing 9 changed files with 104 additions and 117 deletions.
9 changes: 0 additions & 9 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,5 @@ jobs:
steps:
- uses: actions/checkout@v4
- uses: dsherret/rust-toolchain-file@v1
- run: rustup target add wasm32-unknown-unknown
- run: rustup component add rust-src

- run: sudo apt update && sudo apt install -y clang lld
if: ${{ contains(matrix.target, 'linux') }}

- run: brew install llvm
if: ${{ contains(matrix.target, 'apple') }}

- name: Run `make test`
run: make test
1 change: 0 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ contracts: setup-compiler ## Build example contracts
-Z build-std=core,alloc \
--target wasm64-unknown-unknown
@mkdir -p target/stripped
@contracts/c-example/build.sh
@find target/wasm64-unknown-unknown/release -maxdepth 1 -name "*.wasm" \
| xargs -I % basename % \
| xargs -I % ./scripts/strip.sh \
Expand Down
1 change: 1 addition & 0 deletions contracts/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
[workspace]
members = [
"box",
"c-example",
"callcenter",
"constructor",
"counter",
Expand Down
12 changes: 12 additions & 0 deletions contracts/c-example/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[package]
name = "c_example"
version = "0.1.0"
authors = [
"Eduardo Leegwater Simões <[email protected]>",
]
edition = "2021"

license = "MPL-2.0"

[lib]
crate-type = ["cdylib", "rlib"]
13 changes: 0 additions & 13 deletions contracts/c-example/build.sh

This file was deleted.

92 changes: 0 additions & 92 deletions contracts/c-example/contract.c

This file was deleted.

89 changes: 89 additions & 0 deletions contracts/c-example/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Copyright (c) DUSK NETWORK. All rights reserved.

use std::ptr;

// Define the argument buffer used to communicate between contract and host
#[no_mangle]
pub static mut A: [u8; 65536] = [0; 65536];

// ==== Host functions ====
//
// These functions are provided by the host. See `piecrust-uplink` for a full
// list. Here we only declare the ones we will need.
mod ext {
extern "C" {
pub fn c(
contract_id: *const u8,
fn_name: *const u8,
fn_name_len: u32,
fn_arg_len: u32,
points_limit: u64,
) -> i32;
pub fn hd(name: *const u8, name_len: u32) -> u32;
}
}

// ==== Helper functions ====
//
// These will help us write the exported functions underneath

// Reads a contract ID from the argument buffer
unsafe fn read_contract_id(id: *mut u8) {
ptr::copy(&A[0], id, 32);
}

// Calls the counter contract to increment the counter
unsafe fn increment_counter(contract_id: *const u8) {
let fn_name = b"increment";
ext::c(contract_id, fn_name.as_ptr(), fn_name.len() as u32, 0, 0);
}

// Reads a 64-bit from the argument buffer
unsafe fn read_integer(i: *mut i64) {
ptr::copy(&A[0], i.cast(), 8);
}

// Writes a 64-bit integer to the argument buffer
unsafe fn write_integer(i: i64) {
let i: *const i64 = &i;
let i: *const u8 = i as _;
ptr::copy(&*i, &mut A[0], 8);
}

// Calls the counter contract to read the counter
unsafe fn read_counter(contract_id: *const u8) -> i64 {
let fn_name = b"read_value";
ext::c(contract_id, fn_name.as_ptr(), fn_name.len() as u32, 0, 0);

let mut i = 0;
read_integer(&mut i);
i
}

// ==== Exported functions ====

// Increments and reads the counter contract. The function expects the counter
// contract ID to be written to the argument buffer before being called.
#[no_mangle]
unsafe fn increment_and_read(_: i32) -> i32 {
let mut counter_id = [0u8; 32];

read_contract_id(&mut counter_id[0]);
increment_counter(&counter_id[0]);

write_integer(read_counter(&counter_id[0]));

8
}

// Calls the "hd" extern with an (almost) certainly out of bounds pointer, in an
// effort to trigger an error.
#[no_mangle]
unsafe fn out_of_bounds(_: i32) -> i32 {
ext::hd(4398046511103 as *const u8, 2);
0
}
2 changes: 1 addition & 1 deletion piecrust/tests/counter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ fn call_through_c() -> Result<(), Error> {
LIMIT,
)?;
let c_example_id = session.deploy(
contract_bytecode!("c-example"),
contract_bytecode!("c_example"),
ContractData::builder(OWNER),
LIMIT,
)?;
Expand Down
2 changes: 1 addition & 1 deletion piecrust/tests/validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ fn out_of_bounds() -> Result<(), Error> {
let mut session = vm.session(SessionData::builder())?;

let c_example_id = session.deploy(
contract_bytecode!("c-example"),
contract_bytecode!("c_example"),
ContractData::builder(OWNER),
LIMIT,
)?;
Expand Down

0 comments on commit db9ac64

Please sign in to comment.