Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
7a4c4a7
reuse light state in full state
hhalex Oct 9, 2025
5891c9a
adapt
hhalex Oct 9, 2025
ea812a0
fix complex test
hhalex Oct 10, 2025
78fad17
Merge branch 'main' into feat/split_smt_data_from_commitment
hhalex Oct 10, 2025
de7825c
remove fullstate/executionstate duplication
hhalex Oct 13, 2025
461c240
Merge branch 'main' into feat/split_light_full_zk
hhalex Oct 13, 2025
7df6d60
rm files
hhalex Oct 13, 2025
76c2b02
fix server compilation
hhalex Oct 14, 2025
b497e7f
fix compilation 2
hhalex Oct 14, 2025
0dc44e1
fix tests compilation
hhalex Oct 14, 2025
dcc5940
fix tests
hhalex Oct 14, 2025
f2e3066
remove root verification, pimp commit method
hhalex Oct 16, 2025
d1df690
fix server
hhalex Oct 16, 2025
271d8c3
fix clippy
hhalex Oct 16, 2025
75824e2
add default roots when no data, use ZkWitnessSet to simplify
hhalex Oct 16, 2025
34f3b22
fix tests
hhalex Oct 16, 2025
c003fec
fix clippy
hhalex Oct 16, 2025
961d4ff
Merge branch 'main' into feat/split_light_full_zk
hhalex Oct 16, 2025
227a137
fix fmt
hhalex Oct 16, 2025
9defcd7
remove useless function
hhalex Oct 16, 2025
483d365
address comments
hhalex Oct 17, 2025
79bdaa9
Rename to ParsedStateCommitment
hhalex Oct 17, 2025
276fe99
Merge branch 'main' into feat/split_light_full_zk
hhalex Oct 17, 2025
5c4cfda
update contract
hhalex Oct 17, 2025
93b8063
update
hhalex Oct 17, 2025
ab80b7f
fix settlement create-pair
hhalex Oct 17, 2025
ee452f9
add helper to parse state commitment
hhalex Oct 17, 2025
c6486b0
fix balance deposit issue
hhalex Oct 17, 2025
0a2f380
update contract
hhalex Oct 17, 2025
becf2a3
fix fmt
hhalex Oct 17, 2025
d2af061
fix full state missing transition
hhalex Oct 17, 2025
60fcfc5
fix fmt
hhalex Oct 17, 2025
ba8b257
fix clippy tests
hhalex Oct 17, 2025
5f5105c
update user info
hhalex Oct 17, 2025
667166c
fix fmt
hhalex Oct 17, 2025
152c391
basic version compiling
hhalex Oct 17, 2025
bef391c
reintroduce vapp::Logic trait
hhalex Oct 17, 2025
a4ea7f3
Use SMT wrapper + ZkWitness
hhalex Oct 17, 2025
a1bd45b
add Witness Bridge
hhalex Oct 17, 2025
0759be0
simplify Zk witness/SMT fields
hhalex Oct 17, 2025
383936e
use real smt /zkwitness structs
hhalex Oct 17, 2025
f284aef
abstract storage to make fullstate commit data seamlessly
hhalex Oct 17, 2025
0fce102
Make witness state generation automatic
hhalex Oct 20, 2025
0713f04
clean api
hhalex Oct 20, 2025
d4712d1
add tests
hhalex Oct 20, 2025
90f1777
add commit method
hhalex Oct 20, 2025
952f4b2
Merge branch 'main' into feat/test_vapp_macro
maxgttph Oct 22, 2025
0fabaf4
Merge branch 'main' into feat/test_vapp_macro
maxgttph Oct 24, 2025
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
35 changes: 35 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 9 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
[workspace]
resolver = "2"
members = ["contracts", "contracts/orderbook", "server", "loadtest"]
members = [
"macros/state-core",
"macros/state-macros",
"examples/state-example",
"contracts",
"contracts/orderbook",
"server",
"loadtest"
]

[workspace.dependencies]
sdk = { git = "https://github.com/hyli-org/hyli.git", package = "hyli-contract-sdk", branch = "explorer_last_settled_tx" }
Expand Down
11 changes: 11 additions & 0 deletions examples/state-example/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[package]
name = "state-example"
version = "0.1.0"
edition = "2021"

[dependencies]
state-core = { path = "../../macros/state-core" }
state-macros = { path = "../../macros/state-macros" }
borsh = "1.5.7"
sha2 = "0.10.8"
sparse-merkle-tree = { version = "0.6.1", default-features = false }
213 changes: 213 additions & 0 deletions examples/state-example/src/generated.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
use borsh::{BorshDeserialize, BorshSerialize};
use sha2::{Digest, Sha256};
use sparse_merkle_tree::{traits::Value, H256};
use state_core::{BorshableH256, GetHashMapIndex, GetKey};
use state_macros::vapp_state;

#[derive(
Debug, Clone, Default, Eq, PartialEq, PartialOrd, Ord, Hash, BorshSerialize, BorshDeserialize,
)]
pub struct UserInfo {
pub username: String,
pub name: String,
pub nonce: u32,
}

impl GetHashMapIndex<String> for UserInfo {
fn hash_map_index(&self) -> &String {
&self.username
}
}

impl GetKey for UserInfo {
fn get_key(&self) -> BorshableH256 {
let mut hasher = Sha256::new();
hasher.update(self.username.as_bytes());
let result = hasher.finalize();
let mut bytes = [0u8; 32];
bytes.copy_from_slice(&result);
BorshableH256::from(bytes)
}
}

impl Value for UserInfo {
fn to_h256(&self) -> H256 {
if self.nonce == 0 {
return H256::zero();
}
let serialized = borsh::to_vec(self).expect("failed to serialize user info");
let mut hasher = Sha256::new();
hasher.update(&serialized);
let result = hasher.finalize();
let mut bytes = [0u8; 32];
bytes.copy_from_slice(&result);
H256::from(bytes)
}

fn zero() -> Self {
UserInfo {
username: String::new(),
name: String::new(),
nonce: 0,
}
}
}

#[derive(
Debug, Clone, Default, Eq, PartialEq, PartialOrd, Ord, Hash, BorshSerialize, BorshDeserialize,
)]
pub struct Balance {
pub username: String,
pub amount: i64,
}

impl Balance {
pub fn new(username: String) -> Self {
Balance {
username,
amount: 0,
}
}
}

impl GetHashMapIndex<String> for Balance {
fn hash_map_index(&self) -> &String {
&self.username
}
}

impl GetKey for Balance {
fn get_key(&self) -> BorshableH256 {
let mut hasher = Sha256::new();
hasher.update(self.username.as_bytes());
let result = hasher.finalize();
let mut bytes = [0u8; 32];
bytes.copy_from_slice(&result);
BorshableH256::from(bytes)
}
}

impl Value for Balance {
fn to_h256(&self) -> H256 {
if self.amount == 0 {
return H256::zero();
}
let mut hasher = Sha256::new();
hasher.update(self.username.as_bytes());
hasher.update(self.amount.to_le_bytes());
let result = hasher.finalize();
let mut bytes = [0u8; 32];
bytes.copy_from_slice(&result);
H256::from(bytes)
}

fn zero() -> Self {
Balance {
username: String::new(),
amount: 0,
}
}
}

#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct AssetInfo {
pub decimals: u8,
}

#[derive(Debug, Clone)]
pub enum Action {
RegisterUser {
username: String,
name: String,
},
CreditBalance {
symbol: String,
username: String,
amount: i64,
},
}

#[derive(Debug, Clone)]
pub enum Event {
UserRegistered(UserInfo),
BalanceCredited {
symbol: String,
username: String,
amount: i64,
},
}

#[vapp_state(action = Action, event = Event)]
pub struct Vapp {
#[commit(SMT)]
pub user_infos: std::collections::HashMap<String, UserInfo>,

#[commit(SMT)]
pub balances: std::collections::HashMap<String, std::collections::HashMap<String, Balance>>,

#[ident(borsh)]
pub assets: std::collections::HashMap<String, AssetInfo>,
}

impl vapp::Logic for vapp::ExecuteState {
fn compute_events(&self, action: &vapp::Action) -> Vec<vapp::Event> {
match action {
vapp::Action::RegisterUser { username, name } => {
if self.user_infos.contains_key(username) {
vec![]
} else {
vec![vapp::Event::UserRegistered(UserInfo {
username: username.clone(),
name: name.clone(),
nonce: 0,
})]
}
}
vapp::Action::CreditBalance {
symbol,
username,
amount,
} => {
if !self.user_infos.contains_key(username) {
vec![]
} else {
vec![vapp::Event::BalanceCredited {
symbol: symbol.clone(),
username: username.clone(),
amount: *amount,
}]
}
}
}
}

fn apply_events(&mut self, events: &[vapp::Event]) {
for event in events {
match event {
vapp::Event::UserRegistered(user) => {
self.user_infos.insert(
user.username.clone(),
UserInfo {
username: user.username.clone(),
name: user.name.clone(),
nonce: user.nonce,
},
);
}
vapp::Event::BalanceCredited {
symbol,
username,
amount,
} => {
let balance = self
.balances
.entry(symbol.clone())
.or_default()
.entry(username.clone())
.or_insert_with(|| Balance::new(username.clone()));
balance.amount += amount;
}
}
}
}
}
49 changes: 49 additions & 0 deletions examples/state-example/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
mod generated;

use generated::vapp;
use generated::AssetInfo;
use state_core::SMT;
use std::collections::HashMap;

fn main() {
let mut execute = vapp::ExecuteState::default();
execute
.assets
.insert("ETH".into(), AssetInfo { decimals: 18 });

let mut full = vapp::FullState {
execute_state: execute.clone(),
user_infos: SMT::zero(),
balances: HashMap::new(),
assets: execute.assets.clone(),
};

let mut events = Vec::new();

let register_events = full.apply_action(&vapp::Action::RegisterUser {
username: "alice".into(),
name: "Alice".into(),
});

let commit = full.commit();
println!("commit: {commit:?}");

println!("register events: {register_events:?}");
events.extend(register_events);

let credit_events = full.apply_action(&vapp::Action::CreditBalance {
symbol: "ETH".into(),
username: "alice".into(),
amount: 100,
});
println!("credit events: {credit_events:?}");
events.extend(credit_events);

let zk_state = full.build_witness_state(&events);

let commit = zk_state.commit();
println!("commit: {commit:?}");

println!("full: {full:?}");
println!("zk: {zk_state:?}");
}
11 changes: 11 additions & 0 deletions macros/state-core/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[package]
name = "state-core"
version = "0.1.0"
edition = "2021"

[dependencies]
borsh = "1.5.7"
hex = "0.4.3"
sdk = { workspace = true, features = ["smt"] }
sha2 = "0.10.8"
sparse-merkle-tree = { version = "0.6.1", default-features = false }
Loading
Loading