From 6ab60c15ac0a9e8cfe29fabd9a23d70c33b535b9 Mon Sep 17 00:00:00 2001 From: Antonio Yang Date: Mon, 7 Mar 2022 08:44:29 +0800 Subject: [PATCH] Init single-bucket example --- .github/workflows/sb_example.yml | 31 +++++++++++++ Cargo.toml | 1 + examples/sb-contract/.cargo/config | 2 + examples/sb-contract/Cargo.toml | 33 ++++++++++++++ examples/sb-contract/sewup.toml | 5 +++ examples/sb-contract/src/lib.rs | 44 ++++++++++++++++++ sewup-derive/Cargo.toml | 1 + sewup/Cargo.toml | 2 +- sewup/src/single_bucket/mod.rs | 71 ++++++++++++++++++++++++++++-- 9 files changed, 186 insertions(+), 4 deletions(-) create mode 100644 .github/workflows/sb_example.yml create mode 100644 examples/sb-contract/.cargo/config create mode 100644 examples/sb-contract/Cargo.toml create mode 100644 examples/sb-contract/sewup.toml create mode 100644 examples/sb-contract/src/lib.rs diff --git a/.github/workflows/sb_example.yml b/.github/workflows/sb_example.yml new file mode 100644 index 000000000..fe34a9f68 --- /dev/null +++ b/.github/workflows/sb_example.yml @@ -0,0 +1,31 @@ +name: Example + +concurrency: + group: single-bucket-${{ github.head_ref }} + cancel-in-progress: true + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + + workflow_dispatch: + +jobs: + single-bucket-example: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + with: + submodules: recursive + + - uses: cachix/install-nix-action@v15 + with: + nix_path: nixpkgs=channel:nixos-unstable + + - name: Run test + run: nix develop -c 'run-example-test' sb + + - name: Deploy test + run: nix develop -c 'cli-build-test' sb diff --git a/Cargo.toml b/Cargo.toml index ef665f7de..198369d14 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,4 +18,5 @@ exclude = [ "examples/rdb-contract", "examples/rusty-contract", "examples/ballot-contract", + "examples/sb-contract", ] diff --git a/examples/sb-contract/.cargo/config b/examples/sb-contract/.cargo/config new file mode 100644 index 000000000..a3ace1d3d --- /dev/null +++ b/examples/sb-contract/.cargo/config @@ -0,0 +1,2 @@ +[target.'cfg(target_arch="wasm32")'] +rustflags = ["-C", "link-arg=--export-table"] diff --git a/examples/sb-contract/Cargo.toml b/examples/sb-contract/Cargo.toml new file mode 100644 index 000000000..1bea4cff6 --- /dev/null +++ b/examples/sb-contract/Cargo.toml @@ -0,0 +1,33 @@ +[package] +name = "sb-contract" +version = "0.1.0" +authors = ["Antonio Yang "] +edition = "2021" +description = "The example contract using sewup single bucket feature" + +[lib] +path = "src/lib.rs" +crate-type = ["cdylib", "lib"] + +[dependencies] +anyhow = "1.0.40" +serde = "1.0" +serde_derive = "1.0" + +sewup = { version = "*", path = "../../sewup", features = [ "single-bucket" ] } +sewup-derive = { version = "*", path = "../../sewup-derive", features = [ "single-bucket" ] } +thiserror = "1.0.24" + +[profile.release] +incremental = false +panic = "abort" +lto = true +opt-level = "z" + +[profile.release.package.kv-contract] +incremental = false +opt-level = "z" + +[features] +constructor = [] +constructor-test = [] diff --git a/examples/sb-contract/sewup.toml b/examples/sb-contract/sewup.toml new file mode 100644 index 000000000..4ec36daa8 --- /dev/null +++ b/examples/sb-contract/sewup.toml @@ -0,0 +1,5 @@ +# This config file is for examples, it is good for you to ignore this config in your sewup project +[deploy] +url = "http://localhost:8545" +private = "0000000000000000000000000000000000000000000000000000000000000000" +address = "0x0000000000000000000000000000000000000000" diff --git a/examples/sb-contract/src/lib.rs b/examples/sb-contract/src/lib.rs new file mode 100644 index 000000000..1e6623f6a --- /dev/null +++ b/examples/sb-contract/src/lib.rs @@ -0,0 +1,44 @@ +use serde_derive::{Deserialize, Serialize}; +use sewup::SingleBucket; +use sewup_derive::{ewasm_constructor, ewasm_main, ewasm_test, Value}; + +#[derive(Default, Clone, Serialize, Deserialize, Debug, PartialEq, Value)] +struct SimpleStruct { + trust: bool, + description: String, +} + +#[ewasm_constructor] +fn setup() { + use sewup::{ + single_bucket::SingleBucket2, + types::{Raw, Row}, + }; + // (Raw, Row), (Row, SimpleStruct) + let bucket = SingleBucket2::::default(); + bucket + .commit() + .expect("there is no return for constructor currently"); +} + +#[ewasm_main(auto)] +fn main() -> anyhow::Result { + use sewup_derive::{ewasm_fn_sig, ewasm_input_from}; + + let contract = sewup::primitives::Contract::new()?; + + let output = match contract.get_function_selector()? { + _ => return panic!("unhandled"), + }; + + Ok(output) +} + +#[ewasm_test] +mod tests { + use super::*; + #[ewasm_test] + fn test_() { + assert!(true) + } +} diff --git a/sewup-derive/Cargo.toml b/sewup-derive/Cargo.toml index 0b3f310cb..959f8ecce 100644 --- a/sewup-derive/Cargo.toml +++ b/sewup-derive/Cargo.toml @@ -39,6 +39,7 @@ rdb = [] token = [] test = ["rdb", "kv"] debug = [] +single-bucket = ["kv"] [package.metadata.docs.rs] all-features = true diff --git a/sewup/Cargo.toml b/sewup/Cargo.toml index 3a3efcf83..869a7c398 100644 --- a/sewup/Cargo.toml +++ b/sewup/Cargo.toml @@ -40,7 +40,7 @@ token = [ ] kv = [] rdb = [] debug = [] -single-bucket = [] +single-bucket = ["kv"] [package.metadata.docs.rs] all-features = true diff --git a/sewup/src/single_bucket/mod.rs b/sewup/src/single_bucket/mod.rs index 7c886d9a9..8ff9e3158 100644 --- a/sewup/src/single_bucket/mod.rs +++ b/sewup/src/single_bucket/mod.rs @@ -1,15 +1,80 @@ use std::iter::Iterator; use std::marker::PhantomData; +use anyhow::Result; +use ewasm_api::storage_store; +use serde::Serialize; +use serde_derive::Serialize as SerializeDerive; + +use crate::utils::storage_index_to_addr; + +const CONFIG_ADDR: [u8; 32] = [0; 32]; + +pub trait SingleBucket +where + Self: Serialize + Default, +{ + fn commit(&self) -> Result { + let mut buffer = [0u8; 32]; + let bin = bincode::serialize(&self).expect("serialize db binary fail"); + let length = bin.len(); + + let mut len_buffer = bin.len().to_be_bytes(); + len_buffer.swap_with_slice(&mut buffer[28..32]); + + storage_store(&CONFIG_ADDR.into(), &buffer.into()); + + let mut addr: [u8; 32] = [0; 32]; + let mut storage_index = 0; + let mut iter = bin.chunks_exact(32); + while storage_index * 32 < length as usize { + storage_index += 1; + storage_index_to_addr(storage_index, &mut addr); + + if let Some(chunk) = iter.next() { + let part: [u8; 32] = chunk.try_into().unwrap(); + storage_store(&addr.into(), &part.into()); + } else { + let remainder = iter.remainder(); + storage_index_to_addr(storage_index, &mut addr); + let mut part = [0u8; 32]; + for i in 0..length & 31 { + part[i] = remainder[i]; + } + storage_store(&addr.into(), &part.into()); + break; + } + } + Ok(length as u32) + } +} + pub struct Item { phantom_k: PhantomData, phantom_v: PhantomData, } -pub enum Pair { +pub enum Pair1 { Item1(Item), } -pub trait SingleBucket { - type Pairs: Iterator>; +pub trait SingleBucket1: SingleBucket + Default { + type Pairs: Iterator>; +} + +pub enum Pair2 { + Item1(Item), + Item2(Item), +} + +#[derive(Default, SerializeDerive)] +pub struct SingleBucket2 { + phantom_k1: PhantomData, + phantom_v1: PhantomData, + phantom_k2: PhantomData, + phantom_v2: PhantomData, +} +impl SingleBucket + for SingleBucket2 +{ }