Skip to content

Commit

Permalink
feat: support heuristic host transaction slicer
Browse files Browse the repository at this point in the history
  • Loading branch information
Jason committed Oct 6, 2024
1 parent 074d8bc commit d406364
Show file tree
Hide file tree
Showing 9 changed files with 1,028 additions and 136 deletions.
86 changes: 81 additions & 5 deletions crates/host/src/host/ecc_helper/jubjub/mod.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,25 @@
pub mod sum;
use ark_std::Zero;
use delphinus_zkwasm::runtime::monitor::plugins::table::Command;
use halo2_proofs::pairing::bn256::Fr;
use halo2_proofs::pairing::bn256::Fr as BabyJubjubFq;
use num_bigint::BigUint;
use num_traits::FromPrimitive;
use num_traits::Zero;
use std::ops::AddAssign;
use std::ops::Shl;
use zkwasm_host_circuits::circuits::babyjub::AltJubChip;
use zkwasm_host_circuits::circuits::host::HostOpSelector;
use zkwasm_host_circuits::host::jubjub;

const LIMBSZ: usize = 64;
const LIMBNB: usize = 4;
use zkwasm_host_circuits::host::ForeignInst;
use zkwasm_host_circuits::proof::OpType;

use super::bn_to_field;
use super::field_to_bn;
use crate::PluginFlushStrategy;

pub mod sum;

const LIMBSZ: usize = 64;
const LIMBNB: usize = 4;

pub fn fetch_fq(limbs: &[u64], index: usize) -> BabyJubjubFq {
let mut bn = BigUint::zero();
Expand Down Expand Up @@ -42,3 +50,71 @@ pub fn babyjubjub_fq_to_limbs(result_limbs: &mut Vec<u64>, f: BabyJubjubFq) {
result_limbs.append(&mut vec![value]);
}
}

pub(crate) struct JubJubFlushStrategy {
current: usize,
group: usize,
maximal_group: usize,
new_msm: bool,
}

impl JubJubFlushStrategy {
pub(crate) fn new(k: u32) -> Self {
Self {
current: 0,
group: 0,
maximal_group: AltJubChip::<Fr>::max_rounds(k as usize),
new_msm: true,
}
}

fn group_size() -> usize {
// new + scalar + point + result point
1 + 4 + 8 + 8
}
}

impl PluginFlushStrategy for JubJubFlushStrategy {
fn notify(&mut self, op: &ForeignInst, value: Option<u64>) -> Vec<Command> {
let op_type = OpType::JUBJUBSUM as usize;

self.current += 1;

if *op as usize == ForeignInst::JubjubSumNew as usize {
let value = value.unwrap();
assert!(value == 0 || value == 1);

self.new_msm = value == 1;

if self.new_msm {
return vec![Command::Finalize(op_type), Command::Start(op_type)];
} else {
return vec![Command::Start(op_type)];
}
}

if self.current == JubJubFlushStrategy::group_size() {
self.current = 0;
self.group += 1;

let mut commands = vec![Command::Commit(op_type, self.new_msm)];

if self.group >= self.maximal_group {
commands.push(Command::Abort);
}

return commands;
}

vec![Command::Noop]
}

fn reset(&mut self) {
self.current = 0;
self.group = 0;
}

fn maximal_group(&self) -> Option<usize> {
Some(self.maximal_group)
}
}
73 changes: 73 additions & 0 deletions crates/host/src/host/hash_helper/poseidon.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
use delphinus_zkwasm::runtime::host::host_env::HostEnv;
use delphinus_zkwasm::runtime::host::ForeignContext;
use delphinus_zkwasm::runtime::host::ForeignStatics;
use delphinus_zkwasm::runtime::monitor::plugins::table::Command;
use ff::PrimeField;
use halo2_proofs::pairing::bn256::Fr;
use poseidon::Poseidon;
use std::rc::Rc;
pub use zkwasm_host_circuits::host::poseidon::POSEIDON_HASHER;
use zkwasm_host_circuits::host::ForeignInst;
use zkwasm_host_circuits::proof::OpType;

use zkwasm_host_circuits::host::Reduce;
use zkwasm_host_circuits::host::ReduceRule;
Expand Down Expand Up @@ -123,6 +126,8 @@ impl ForeignContext for PoseidonContext {
}

use specs::external_host_call_table::ExternalHostCallSignature;

use crate::PluginFlushStrategy;
pub fn register_poseidon_foreign(env: &mut HostEnv) {
let foreign_poseidon_plugin = env
.external_env
Expand Down Expand Up @@ -170,3 +175,71 @@ pub fn register_poseidon_foreign(env: &mut HostEnv) {
),
);
}

pub(crate) struct PoseidonFlushStrategy {
current: usize,
group: usize,
maximal_group: usize,
new_hasher: bool,
}

impl PoseidonFlushStrategy {
pub(crate) fn new(k: u32) -> Self {
Self {
current: 0,
group: 0,
maximal_group: PoseidonChip::max_rounds(k as usize),
new_hasher: true,
}
}

fn group_size() -> usize {
// new + push + result
1 + 4 * 8 + 4
}
}

impl PluginFlushStrategy for PoseidonFlushStrategy {
fn notify(&mut self, op: &ForeignInst, value: Option<u64>) -> Vec<Command> {
let op_type = OpType::POSEIDONHASH as usize;

self.current += 1;

if *op as usize == ForeignInst::PoseidonNew as usize {
let value = value.unwrap();
assert!(value == 0 || value == 1);

self.new_hasher = value == 1;

if self.new_hasher {
return vec![Command::Finalize(op_type), Command::Start(op_type)];
} else {
return vec![Command::Start(op_type)];
}
}

if self.current == PoseidonFlushStrategy::group_size() {
self.current = 0;
self.group += 1;

let mut commands = vec![Command::Commit(op_type, self.new_hasher)];

if self.group >= self.maximal_group {
commands.push(Command::Abort);
}

return commands;
}

vec![Command::Noop]
}

fn reset(&mut self) {
self.current = 0;
self.group = 0;
}

fn maximal_group(&self) -> Option<usize> {
Some(self.maximal_group)
}
}
83 changes: 83 additions & 0 deletions crates/host/src/host/merkle_helper/mod.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,85 @@
use delphinus_zkwasm::runtime::monitor::plugins::table::Command;
use halo2_proofs::pairing::bn256::Fr;
use zkwasm_host_circuits::circuits::host::HostOpSelector;
use zkwasm_host_circuits::circuits::merkle::MerkleChip;
use zkwasm_host_circuits::host::ForeignInst;
use zkwasm_host_circuits::proof::OpType;

use crate::PluginFlushStrategy;
use crate::MERKLE_TREE_HEIGHT;

pub mod datacache;
pub mod merkle;

pub(crate) struct MerkleFlushStrategy {
current: usize,
group: usize,
maximal_group: usize,
is_set: bool,
}

impl MerkleFlushStrategy {
pub(crate) fn new(k: u32) -> Self {
Self {
current: 0,
group: 0,
maximal_group: MerkleChip::<Fr, MERKLE_TREE_HEIGHT>::max_rounds(k as usize),
is_set: false,
}
}

fn group_size() -> usize {
// address + set_root + get/set + get_root
1 + 4 + 4 + 4
}
}

impl PluginFlushStrategy for MerkleFlushStrategy {
fn notify(&mut self, op: &ForeignInst, _value: Option<u64>) -> Vec<Command> {
let op_type = OpType::MERKLE as usize;

self.current += 1;

if *op as usize == ForeignInst::MerkleAddress as usize {
self.is_set = false;

return vec![Command::Start(op_type)];
}

if *op as usize == ForeignInst::MerkleSet as usize {
self.is_set = true;
}

if *op as usize == ForeignInst::MerkleGet as usize {
return vec![Command::Finalize(op_type), Command::Noop];
}

if self.current == MerkleFlushStrategy::group_size() {
self.current = 0;
self.group += 1;

let mut commands = if self.is_set {
vec![Command::Commit(op_type, false), Command::Finalize(op_type)]
} else {
vec![Command::Commit(op_type, true)]
};

if self.group >= self.maximal_group {
commands.push(Command::Abort);
}

return commands;
}

vec![Command::Noop]
}

fn reset(&mut self) {
self.current = 0;
self.group = 0;
}

fn maximal_group(&self) -> Option<usize> {
Some(self.maximal_group)
}
}
Loading

0 comments on commit d406364

Please sign in to comment.