From f4951b499a2f54dd5267b6fa24da44da004d8739 Mon Sep 17 00:00:00 2001 From: Izumi Hoshino Date: Fri, 24 Nov 2023 06:06:56 +0900 Subject: [PATCH 1/6] WIP: introducing wasm-pack --- Cargo.lock | 28 +- chia-protocol/Cargo.toml | 6 +- chia-protocol/src/bytes.rs | 381 ++++++++++++++++++++++++++++ chia-protocol/src/coin.rs | 43 +++- chia-protocol/src/message_struct.rs | 22 ++ wasm/Cargo.toml | 2 +- 6 files changed, 466 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 318959030..06afb444e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -371,9 +371,11 @@ dependencies = [ "clvm-traits", "clvmr", "hex", + "paste", "pyo3", "rstest 0.17.0", "sha2 0.10.8", + "wasm-bindgen", ] [[package]] @@ -1508,6 +1510,12 @@ dependencies = [ "windows-targets", ] +[[package]] +name = "paste" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" + [[package]] name = "pbkdf2" version = "0.11.0" @@ -2561,9 +2569,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.87" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +checksum = "7daec296f25a1bae309c0cd5c29c4b260e510e6d813c286b19eaadf409d40fce" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -2571,9 +2579,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.87" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +checksum = "e397f4664c0e4e428e8313a469aaa58310d302159845980fd23b0f22a847f217" dependencies = [ "bumpalo", "log", @@ -2598,9 +2606,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.87" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +checksum = "5961017b3b08ad5f3fe39f1e79877f8ee7c23c5e5fd5eb80de95abc41f1f16b2" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2608,9 +2616,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.87" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +checksum = "c5353b8dab669f5e10f5bd76df26a9360c748f054f862ff5f3f8aae0c7fb3907" dependencies = [ "proc-macro2", "quote", @@ -2621,9 +2629,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.87" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" +checksum = "0d046c5d029ba91a1ed14da14dca44b68bf2f124cfbaf741c54151fdb3e0750b" [[package]] name = "wasm-bindgen-test" diff --git a/chia-protocol/Cargo.toml b/chia-protocol/Cargo.toml index 1c4af1172..c7e405906 100644 --- a/chia-protocol/Cargo.toml +++ b/chia-protocol/Cargo.toml @@ -23,8 +23,12 @@ clvm-traits = { version = "=0.2.12", path = "../clvm-traits", features = ["deriv chia-bls = { version = "0.2.13", path = "../chia-bls" } arbitrary = { version = "1.3.0", features = ["derive"] } +[target.'cfg(target_arch = "wasm32")'.dependencies] +wasm-bindgen = "0.2.88" +paste = "1.0.14" + [dev-dependencies] rstest = "0.17.0" [lib] -crate-type = ["rlib"] +crate-type = ["rlib", "cdylib"] diff --git a/chia-protocol/src/bytes.rs b/chia-protocol/src/bytes.rs index 01f6d57bb..79e71d82f 100644 --- a/chia-protocol/src/bytes.rs +++ b/chia-protocol/src/bytes.rs @@ -12,6 +12,9 @@ use std::fmt::Debug; use std::io::Cursor; use std::ops::Deref; +use wasm_bindgen::prelude::*; +use paste::paste; + #[cfg(feature = "py-bindings")] use chia_traits::{FromJsonDict, ToJsonDict}; #[cfg(feature = "py-bindings")] @@ -23,6 +26,7 @@ use pyo3::prelude::*; #[cfg(feature = "py-bindings")] use pyo3::types::PyBytes; +#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] #[derive(Hash, Clone, Eq, PartialEq, PartialOrd, Ord)] #[cfg_attr(fuzzing, derive(arbitrary::Arbitrary))] pub struct Bytes(Vec); @@ -187,6 +191,21 @@ impl fmt::Display for Bytes { #[cfg_attr(fuzzing, derive(arbitrary::Arbitrary))] pub struct BytesImpl([u8; N]); +macro_rules! generate_bytes_n { + ($($N:expr),+) => { + paste! { + $( + #[cfg(target_arch = "wasm32")] + #[wasm_bindgen] + #[derive(Hash, PartialEq, Eq, Copy, Clone, PartialOrd, Ord)] + #[cfg_attr(fuzzing, derive(arbitrary::Arbitrary))] + pub struct []([u8; $N]); + )+ + } + }; +} +generate_bytes_n!(32, 48, 96, 100); + impl Streamable for BytesImpl { fn update_digest(&self, digest: &mut Sha256) { digest.update(self.0); @@ -201,12 +220,52 @@ impl Streamable for BytesImpl { } } +macro_rules! impl_streamable_for_bytes_n { + ($($N:expr),+) => { + paste! { + $( + #[cfg(target_arch = "wasm32")] + impl Streamable for [] { + fn update_digest(&self, digest: &mut Sha256) { + digest.update(self.0); + } + fn stream(&self, out: &mut Vec) -> chia_error::Result<()> { + out.extend_from_slice(&self.0); + Ok(()) + } + + fn parse(input: &mut Cursor<&[u8]>) -> chia_error::Result { + Ok([](read_bytes(input, $N)?.try_into().unwrap())) + } + } + )+ + } + }; +} +impl_streamable_for_bytes_n!(32, 48, 96, 100); + impl ToClvm for BytesImpl { fn to_clvm(&self, a: &mut Allocator) -> clvm_traits::Result { Ok(a.new_atom(self.0.as_slice())?) } } +macro_rules! impl_to_clvm_for_bytes_n { + ($($N:expr),+) => { + paste! { + $( + #[cfg(target_arch = "wasm32")] + impl ToClvm for [] { + fn to_clvm(&self, a: &mut Allocator) -> clvm_traits::Result { + Ok(a.new_atom(self.0.as_slice())?) + } + } + )+ + } + }; +} +impl_to_clvm_for_bytes_n!(32, 48, 96, 100); + impl FromClvm for BytesImpl { fn from_clvm(a: &Allocator, ptr: NodePtr) -> clvm_traits::Result { let blob = match a.sexp(ptr) { @@ -224,16 +283,77 @@ impl FromClvm for BytesImpl { } } +macro_rules! impl_from_clvm_for_bytes_n { + ($($N:expr),+) => { + paste! { + $( + #[cfg(target_arch = "wasm32")] + impl FromClvm for [] { + fn from_clvm(a: &Allocator, ptr: NodePtr) -> clvm_traits::Result { + let blob = match a.sexp(ptr) { + SExp::Atom => { + if a.atom_len(ptr) != $N { + return Err(clvm_traits::Error::Custom("invalid size".to_string())); + } + a.atom(ptr) + } + _ => { + return Err(clvm_traits::Error::ExpectedAtom(ptr)); + } + }; + Ok(Self::from(blob)) + } + } + )+ + } + }; +} +impl_from_clvm_for_bytes_n!(32, 48, 96, 100); + impl From<[u8; N]> for BytesImpl { fn from(v: [u8; N]) -> BytesImpl { BytesImpl::(v) } } + +macro_rules! impl_from_u8n_for_bytes_n { + ($($N:expr),+) => { + paste! { + $( + #[cfg(target_arch = "wasm32")] + impl From<[u8; $N]> for [] { + fn from(v: [u8; $N]) -> [] { + [](v) + } + } + )+ + } + }; +} +impl_from_u8n_for_bytes_n!(32, 48, 96, 100); + impl From<&[u8; N]> for BytesImpl { fn from(v: &[u8; N]) -> BytesImpl { BytesImpl::(*v) } } + +macro_rules! impl_from_ref_u8n_for_bytes_n { + ($($N:expr),+) => { + paste! { + $( + #[cfg(target_arch = "wasm32")] + impl From<&[u8; $N]> for [] { + fn from(v: &[u8; $N]) -> [] { + [](*v) + } + } + )+ + } + }; +} +impl_from_ref_u8n_for_bytes_n!(32, 48, 96, 100); + impl From<&[u8]> for BytesImpl { fn from(v: &[u8]) -> BytesImpl { if v.len() != N { @@ -244,6 +364,28 @@ impl From<&[u8]> for BytesImpl { ret } } + +macro_rules! impl_from_ref_u8_for_bytes_n { + ($($N:expr),+) => { + paste! { + $( + #[cfg(target_arch = "wasm32")] + impl From<&[u8]> for [] { + fn from(v: &[u8]) -> [] { + if v.len() != $N { + panic!("invalid atom, expected {} bytes (got {})", $N, v.len()); + } + let mut ret = []([0; $N]); + ret.0.copy_from_slice(v); + ret + } + } + )+ + } + }; +} +impl_from_ref_u8_for_bytes_n!(32, 48, 96, 100); + impl From<&Vec> for BytesImpl { fn from(v: &Vec) -> BytesImpl { if v.len() != N { @@ -254,88 +396,323 @@ impl From<&Vec> for BytesImpl { ret } } + +macro_rules! impl_from_ref_vec_u8_for_bytes_n { + ($($N:expr),+) => { + paste! { + $( + #[cfg(target_arch = "wasm32")] + impl From<&Vec> for [] { + fn from(v: &Vec) -> [] { + if v.len() != $N { + panic!("invalid atom, expected {} bytes (got {})", $N, v.len()); + } + let mut ret = []([0; $N]); + ret.0.copy_from_slice(v); + ret + } + } + )+ + } + }; +} +impl_from_ref_vec_u8_for_bytes_n!(32, 48, 96, 100); + impl<'a, const N: usize> From<&'a BytesImpl> for &'a [u8; N] { fn from(v: &'a BytesImpl) -> &'a [u8; N] { &v.0 } } +macro_rules! impl_from_a_bytes_u8_for_a_u8n { + ($($N:expr),+) => { + paste! { + $( + #[cfg(target_arch = "wasm32")] + impl<'a> From<&'a []> for &'a [u8; $N] { + fn from(v: &'a []) -> &'a [u8; $N] { + &v.0 + } + } + )+ + } + }; +} +impl_from_a_bytes_u8_for_a_u8n!(32, 48, 96, 100); + impl From<&BytesImpl> for [u8; N] { fn from(v: &BytesImpl) -> [u8; N] { v.0 } } +macro_rules! impl_from_ref_bytes_n_for_u8n { + ($($N:expr),+) => { + paste! { + $( + #[cfg(target_arch = "wasm32")] + impl From<&[]> for [u8; $N] { + fn from(v: &[]) -> [u8; $N] { + v.0 + } + } + )+ + } + }; +} +impl_from_ref_bytes_n_for_u8n!(32, 48, 96, 100); + impl<'a, const N: usize> From<&'a BytesImpl> for &'a [u8] { fn from(v: &'a BytesImpl) -> &'a [u8] { &v.0 } } +macro_rules! impl_from_a_bytes_n_for_a_u8 { + ($($N:expr),+) => { + paste! { + $( + #[cfg(target_arch = "wasm32")] + impl<'a> From<&'a []> for &'a [u8] { + fn from(v: &'a []) -> &'a [u8] { + &v.0 + } + } + )+ + } + }; +} +impl_from_a_bytes_n_for_a_u8!(32, 48, 96, 100); impl BytesImpl { pub fn to_vec(&self) -> Vec { self.0.to_vec() } } +macro_rules! impl_bytes_n { + ($($N:expr),+) => { + paste! { + $( + #[cfg(target_arch = "wasm32")] + impl [] { + pub fn to_vec(&self) -> Vec { + self.0.to_vec() + } + } + )+ + } + }; +} +impl_bytes_n!(32, 48, 96, 100); impl AsRef<[u8]> for BytesImpl { fn as_ref(&self) -> &[u8] { &self.0 } } + +macro_rules! impl_as_ref_for_bytes_n { + ($($N:expr),+) => { + paste! { + $( + #[cfg(target_arch = "wasm32")] + impl AsRef<[u8]> for [] { + fn as_ref(&self) -> &[u8] { &self.0 } + } + )+ + } + }; +} +impl_as_ref_for_bytes_n!(32, 48, 96, 100); + impl Deref for BytesImpl { type Target = [u8]; fn deref(&self) -> &[u8] { &self.0 } } + +macro_rules! impl_deref_for_bytes_n { + ($($N:expr),+) => { + paste! { + $( + #[cfg(target_arch = "wasm32")] + impl Deref for [] { + type Target = [u8]; + fn deref(&self) -> &[u8] { &self.0 } + } + )+ + } + }; +} +impl_deref_for_bytes_n!(32, 48, 96, 100); + impl Debug for BytesImpl { fn fmt(&self, formatter: &mut Formatter<'_>) -> std::result::Result<(), std::fmt::Error> { formatter.write_str(&hex::encode(self.0)) } } + +macro_rules! impl_debug_for_bytes_n { + ($($N:expr),+) => { + paste! { + $( + #[cfg(target_arch = "wasm32")] + impl Debug for [] { + fn fmt(&self, formatter: &mut Formatter<'_>) -> std::result::Result<(), std::fmt::Error> { + formatter.write_str(&hex::encode(self.0)) + } + } + )+ + } + }; +} +impl_debug_for_bytes_n!(32, 48, 96, 100); + impl fmt::Display for BytesImpl { fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str(&hex::encode(self.0)) } } +macro_rules! impl_display_for_bytes_n { + ($($N:expr),+) => { + paste! { + $( + #[cfg(target_arch = "wasm32")] + impl fmt::Display for [] { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str(&hex::encode(self.0)) + } + } + )+ + } + }; +} +impl_display_for_bytes_n!(32, 48, 96, 100); + impl PartialEq<&[u8]> for BytesImpl { fn eq(&self, lhs: &&[u8]) -> bool { self.0 == *lhs } } +macro_rules! impl_partial_eq_for_ref_bytes_n { + ($($N:expr),+) => { + paste! { + $( + #[cfg(target_arch = "wasm32")] + impl PartialEq<&[u8]> for [] { + fn eq(&self, lhs: &&[u8]) -> bool { self.0 == *lhs } + } + )+ + } + }; +} +impl_partial_eq_for_ref_bytes_n!(32, 48, 96, 100); + impl PartialEq> for &[u8] { fn eq(&self, lhs: &BytesImpl) -> bool { self == &lhs.0 } } +macro_rules! impl_partial_eq_for_ref_u8 { + ($($N:expr),+) => { + paste! { + $( + #[cfg(target_arch = "wasm32")] + impl PartialEq<[]> for &[u8] { + fn eq(&self, lhs: &[]) -> bool { self == &lhs.0 } + } + )+ + } + }; +} +impl_partial_eq_for_ref_u8!(32, 48, 96, 100); + impl PartialEq<&[u8; N]> for BytesImpl { fn eq(&self, lhs: &&[u8; N]) -> bool { &self.0 == *lhs } } +macro_rules! impl_partial_eq_ref_u8n_for_bytes_n { + ($($N:expr),+) => { + paste! { + $( + #[cfg(target_arch = "wasm32")] + impl PartialEq<&[u8; $N]> for [] { + fn eq(&self, lhs: &&[u8; $N]) -> bool { &self.0 == *lhs } + } + )+ + } + }; +} +impl_partial_eq_ref_u8n_for_bytes_n!(32, 48, 96, 100); + impl PartialEq> for &[u8; N] { fn eq(&self, lhs: &BytesImpl) -> bool { *self == &lhs.0 } } +macro_rules! impl_partial_eq_bytes_n_for_ref_u8n { + ($($N:expr),+) => { + paste! { + $( + #[cfg(target_arch = "wasm32")] + impl PartialEq<[]> for &[u8; $N] { + fn eq(&self, lhs: &[]) -> bool { *self == &lhs.0 } + } + )+ + } + }; +} +impl_partial_eq_bytes_n_for_ref_u8n!(32, 48, 96, 100); + impl PartialEq<[u8; N]> for BytesImpl { fn eq(&self, lhs: &[u8; N]) -> bool { &self.0 == lhs } } +macro_rules! impl_partial_eq_u8n_for_bytes_n { + ($($N:expr),+) => { + paste! { + $( + #[cfg(target_arch = "wasm32")] + impl PartialEq<[u8; $N]> for [] { + fn eq(&self, lhs: &[u8; $N]) -> bool { + &self.0 == lhs + } + } + )+ + } + }; +} +impl_partial_eq_u8n_for_bytes_n!(32, 48, 96, 100); + + impl PartialEq> for [u8; N] { fn eq(&self, lhs: &BytesImpl) -> bool { self == &lhs.0 } } +macro_rules! impl_partial_eq_bytes_n_for_u8n { + ($($N:expr),+) => { + paste! { + $( + #[cfg(target_arch = "wasm32")] + impl PartialEq<[]> for [u8; $N] { + fn eq(&self, lhs: &[]) -> bool { self == &lhs.0 } + } + )+ + } + }; +} +impl_partial_eq_bytes_n_for_u8n!(32, 48, 96, 100); + #[cfg(feature = "py-bindings")] impl ToJsonDict for BytesImpl { fn to_json_dict(&self, py: Python) -> PyResult { @@ -370,9 +747,13 @@ impl FromJsonDict for BytesImpl { } } +#[cfg(not(target_arch = "wasm32"))] pub type Bytes32 = BytesImpl<32>; +#[cfg(not(target_arch = "wasm32"))] pub type Bytes48 = BytesImpl<48>; +#[cfg(not(target_arch = "wasm32"))] pub type Bytes96 = BytesImpl<96>; +#[cfg(not(target_arch = "wasm32"))] pub type Bytes100 = BytesImpl<100>; #[cfg(feature = "py-bindings")] diff --git a/chia-protocol/src/coin.rs b/chia-protocol/src/coin.rs index e66551172..956d52b5b 100644 --- a/chia-protocol/src/coin.rs +++ b/chia-protocol/src/coin.rs @@ -1,5 +1,5 @@ -use crate::streamable_struct; -use crate::{bytes::Bytes32, BytesImpl}; +// use crate::streamable_struct2; +use crate::{bytes::Bytes32}; use chia_streamable_macro::Streamable; use clvm_traits::{clvm_list, destructure_list, match_list, FromClvm, ToClvm}; use clvmr::allocator::NodePtr; @@ -10,12 +10,47 @@ use std::convert::TryInto; #[cfg(feature = "py-bindings")] use pyo3::prelude::*; -streamable_struct!(Coin { +use wasm_bindgen::prelude::*; + +/* +streamable_struct2!(Coin { parent_coin_info: Bytes32, puzzle_hash: Bytes32, amount: u64, }); +// */ + +//* +#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] +#[derive(Streamable, Hash, Debug, Clone, Eq, PartialEq)] +pub struct Coin { + #[wasm_bindgen] + pub parent_coin_info: Bytes32, + #[wasm_bindgen] + pub puzzle_hash: Bytes32, + #[wasm_bindgen] + pub amount: u64, +} + +#[cfg(not(feature = "py-bindings"))] +#[allow(clippy::too_many_arguments)] +impl Coin { + pub fn new ( + parent_coin_info: Bytes32, + puzzle_hash: Bytes32, + amount: u64, + ) -> Coin { + Coin { + parent_coin_info, + puzzle_hash, + amount, + } + } +} +// */ + + impl Coin { pub fn coin_id(&self) -> [u8; 32] { let mut hasher = Sha256::new(); @@ -62,7 +97,7 @@ impl ToClvm for Coin { impl FromClvm for Coin { fn from_clvm(a: &Allocator, ptr: NodePtr) -> clvm_traits::Result { let destructure_list!(parent_coin_info, puzzle_hash, amount) = - , BytesImpl<32>, u64)>::from_clvm(a, ptr)?; + ::from_clvm(a, ptr)?; Ok(Coin { parent_coin_info, puzzle_hash, diff --git a/chia-protocol/src/message_struct.rs b/chia-protocol/src/message_struct.rs index 111163667..f4cfc5e02 100644 --- a/chia-protocol/src/message_struct.rs +++ b/chia-protocol/src/message_struct.rs @@ -43,3 +43,25 @@ macro_rules! streamable_struct { } } } + +#[macro_export] +macro_rules! streamable_struct2 { + ($name:ident {$($field:ident: $t:ty $(,)? )*}) => { + #[wasm_bindgen] + #[derive(Streamable, Hash, Debug, Clone, Eq, PartialEq)] + pub struct $name { + $( + #[wasm_bindgen] + pub $field: $t + ),* + } + + #[cfg(not(feature = "py-bindings"))] + #[allow(clippy::too_many_arguments)] + impl $name { + pub fn new ( $($field: $t),* ) -> $name { + $name { $($field),* } + } + } + } +} diff --git a/wasm/Cargo.toml b/wasm/Cargo.toml index dc1bafcc7..52e5e24bc 100644 --- a/wasm/Cargo.toml +++ b/wasm/Cargo.toml @@ -16,6 +16,6 @@ path = "src/lib.rs" [dependencies] chia = { path = ".." } -wasm-bindgen = "=0.2.87" +wasm-bindgen = "=0.2.88" wasm-bindgen-test = "=0.3.37" js-sys = "=0.3.64" From de13bbc64c1f7007730d318a5eb0d1d8eff7eafc Mon Sep 17 00:00:00 2001 From: Izumi Hoshino Date: Thu, 30 Nov 2023 23:08:29 +0900 Subject: [PATCH 2/6] Checkpoint --- Cargo.lock | 49 ++++++++++++++++++----------- Cargo.toml | 1 + chia-bls/Cargo.toml | 4 +++ chia-bls/src/gtelement.rs | 1 + chia-bls/src/public_key.rs | 1 + chia-bls/src/secret_key.rs | 1 + chia-bls/src/signature.rs | 1 + chia-protocol/Cargo.toml | 1 + chia-protocol/src/chia_protocol.rs | 2 ++ chia-protocol/src/coin.rs | 41 ++---------------------- chia-protocol/src/message_struct.rs | 24 ++------------ chia-protocol/src/program.rs | 1 + wasm-patch/Cargo.toml | 14 +++++++++ wasm-patch/src/lib.rs | 33 +++++++++++++++++++ wasm/Cargo.toml | 1 + 15 files changed, 97 insertions(+), 78 deletions(-) create mode 100644 wasm-patch/Cargo.toml create mode 100644 wasm-patch/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 06afb444e..e024ba123 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -321,6 +321,8 @@ dependencies = [ "sha2 0.10.8", "thiserror", "tiny-bip39", + "wasm-bindgen", + "wasm-patch", ] [[package]] @@ -376,6 +378,7 @@ dependencies = [ "rstest 0.17.0", "sha2 0.10.8", "wasm-bindgen", + "wasm-patch", ] [[package]] @@ -468,7 +471,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.39", ] [[package]] @@ -478,7 +481,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.39", ] [[package]] @@ -486,6 +489,7 @@ name = "chia_wasm" version = "0.2.7" dependencies = [ "chia", + "chia-protocol", "js-sys", "wasm-bindgen", "wasm-bindgen-test", @@ -551,7 +555,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.39", ] [[package]] @@ -566,7 +570,7 @@ version = "0.2.12" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.39", ] [[package]] @@ -800,7 +804,7 @@ checksum = "53e0efad4403bfc52dc201159c4b842a246a14b98c64b55dfd0f2d89729dfeb8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.39", ] [[package]] @@ -832,7 +836,7 @@ checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.39", ] [[package]] @@ -990,7 +994,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.39", ] [[package]] @@ -1650,9 +1654,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.66" +version = "1.0.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" +checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" dependencies = [ "unicode-ident", ] @@ -1720,9 +1724,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.32" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ "proc-macro2", ] @@ -2086,7 +2090,7 @@ checksum = "67c5609f394e5c2bd7fc51efda478004ea80ef42fee983d5c67a65e34f32c0e3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.39", ] [[package]] @@ -2247,9 +2251,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.28" +version = "2.0.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04361975b3f5e348b2189d8dc55bc942f278b2d482a6a0365de5bdd62d351567" +checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" dependencies = [ "proc-macro2", "quote", @@ -2317,7 +2321,7 @@ checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.39", ] [[package]] @@ -2588,7 +2592,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.39", "wasm-bindgen-shared", ] @@ -2622,7 +2626,7 @@ checksum = "c5353b8dab669f5e10f5bd76df26a9360c748f054f862ff5f3f8aae0c7fb3907" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.39", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -2657,6 +2661,15 @@ dependencies = [ "quote", ] +[[package]] +name = "wasm-patch" +version = "0.1.0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + [[package]] name = "web-sys" version = "0.3.64" @@ -2838,7 +2851,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.39", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index ff5cc3458..45d7e1c24 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,6 +20,7 @@ members = [ "clvm-utils/fuzz", "fuzz", "wasm", + "wasm-patch", ] exclude = ["wheel"] diff --git a/chia-bls/Cargo.toml b/chia-bls/Cargo.toml index fb70d8d41..4674af341 100644 --- a/chia-bls/Cargo.toml +++ b/chia-bls/Cargo.toml @@ -26,6 +26,10 @@ thiserror = "1.0.44" pyo3 = { version = "0.19.0", features = ["multiple-pymethods"], optional = true } arbitrary = { version = "1.3.0" } +[target.'cfg(target_arch = "wasm32")'.dependencies] +wasm-bindgen = "0.2.88" +wasm-patch = { version = "0.1.0", path = "../wasm-patch" } + [dev-dependencies] rand = "0.8.5" criterion = "0.5.1" diff --git a/chia-bls/src/gtelement.rs b/chia-bls/src/gtelement.rs index 818085f1c..18112db10 100644 --- a/chia-bls/src/gtelement.rs +++ b/chia-bls/src/gtelement.rs @@ -19,6 +19,7 @@ use pyo3::exceptions::PyValueError; #[cfg(feature = "py-bindings")] use pyo3::{pyclass, pymethods, IntoPy, PyAny, PyObject, PyResult, Python}; +#[wasm_patch::with_wasm] #[cfg_attr(feature = "py-bindings", pyclass, derive(PyStreamable, Clone))] pub struct GTElement(pub(crate) blst_fp12); diff --git a/chia-bls/src/public_key.rs b/chia-bls/src/public_key.rs index 33a376ad1..7798f601b 100644 --- a/chia-bls/src/public_key.rs +++ b/chia-bls/src/public_key.rs @@ -22,6 +22,7 @@ use chia_traits::to_json_dict::ToJsonDict; #[cfg(feature = "py-bindings")] use pyo3::{pyclass, pymethods, IntoPy, PyAny, PyObject, PyResult, Python}; +#[wasm_patch::with_wasm] #[cfg_attr( feature = "py-bindings", pyclass(name = "G1Element"), diff --git a/chia-bls/src/secret_key.rs b/chia-bls/src/secret_key.rs index ceb0d38a6..26996d29a 100644 --- a/chia-bls/src/secret_key.rs +++ b/chia-bls/src/secret_key.rs @@ -22,6 +22,7 @@ use chia_traits::to_json_dict::ToJsonDict; #[cfg(feature = "py-bindings")] use pyo3::{pyclass, pymethods, IntoPy, PyAny, PyObject, PyResult, Python}; +#[wasm_patch::with_wasm] #[cfg_attr( feature = "py-bindings", pyclass(frozen, name = "PrivateKey"), diff --git a/chia-bls/src/signature.rs b/chia-bls/src/signature.rs index 4e3c77574..8f0725573 100644 --- a/chia-bls/src/signature.rs +++ b/chia-bls/src/signature.rs @@ -26,6 +26,7 @@ use pyo3::{pyclass, pymethods, IntoPy, PyAny, PyObject, PyResult, Python}; // we use the augmented scheme pub const DST: &[u8] = b"BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_AUG_"; +#[wasm_patch::with_wasm] #[cfg_attr( feature = "py-bindings", pyclass(name = "G2Element"), diff --git a/chia-protocol/Cargo.toml b/chia-protocol/Cargo.toml index c7e405906..fb72e29b2 100644 --- a/chia-protocol/Cargo.toml +++ b/chia-protocol/Cargo.toml @@ -26,6 +26,7 @@ arbitrary = { version = "1.3.0", features = ["derive"] } [target.'cfg(target_arch = "wasm32")'.dependencies] wasm-bindgen = "0.2.88" paste = "1.0.14" +wasm-patch = { version = "0.1.0", path = "../wasm-patch" } [dev-dependencies] rstest = "0.17.0" diff --git a/chia-protocol/src/chia_protocol.rs b/chia-protocol/src/chia_protocol.rs index b2fd2a653..663c8c860 100644 --- a/chia-protocol/src/chia_protocol.rs +++ b/chia-protocol/src/chia_protocol.rs @@ -7,6 +7,7 @@ use crate::Bytes; #[cfg(feature = "py-bindings")] use chia_py_streamable_macro::{PyJsonDict, PyStreamable}; +#[wasm_patch::with_wasm] #[repr(u8)] #[cfg_attr(feature = "py-bindings", derive(PyJsonDict, PyStreamable))] #[cfg_attr(fuzzing, derive(arbitrary::Arbitrary))] @@ -127,6 +128,7 @@ pub trait ChiaProtocolMessage { fn msg_type() -> ProtocolMessageTypes; } +#[wasm_patch::with_wasm] #[repr(u8)] #[cfg_attr(feature = "py-bindings", derive(PyJsonDict, PyStreamable))] #[cfg_attr(fuzzing, derive(arbitrary::Arbitrary))] diff --git a/chia-protocol/src/coin.rs b/chia-protocol/src/coin.rs index 956d52b5b..1afc62126 100644 --- a/chia-protocol/src/coin.rs +++ b/chia-protocol/src/coin.rs @@ -1,5 +1,4 @@ -// use crate::streamable_struct2; -use crate::{bytes::Bytes32}; +use crate::bytes::Bytes32; use chia_streamable_macro::Streamable; use clvm_traits::{clvm_list, destructure_list, match_list, FromClvm, ToClvm}; use clvmr::allocator::NodePtr; @@ -10,47 +9,13 @@ use std::convert::TryInto; #[cfg(feature = "py-bindings")] use pyo3::prelude::*; -use wasm_bindgen::prelude::*; - -/* -streamable_struct2!(Coin { +//* +crate::streamable_struct!(Coin { parent_coin_info: Bytes32, puzzle_hash: Bytes32, amount: u64, }); -// */ - -//* -#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] -#[derive(Streamable, Hash, Debug, Clone, Eq, PartialEq)] -pub struct Coin { - #[wasm_bindgen] - pub parent_coin_info: Bytes32, - #[wasm_bindgen] - pub puzzle_hash: Bytes32, - #[wasm_bindgen] - pub amount: u64, -} - -#[cfg(not(feature = "py-bindings"))] -#[allow(clippy::too_many_arguments)] -impl Coin { - pub fn new ( - parent_coin_info: Bytes32, - puzzle_hash: Bytes32, - amount: u64, - ) -> Coin { - Coin { - parent_coin_info, - puzzle_hash, - amount, - } - } -} -// */ - - impl Coin { pub fn coin_id(&self) -> [u8; 32] { let mut hasher = Sha256::new(); diff --git a/chia-protocol/src/message_struct.rs b/chia-protocol/src/message_struct.rs index f4cfc5e02..d6d267653 100644 --- a/chia-protocol/src/message_struct.rs +++ b/chia-protocol/src/message_struct.rs @@ -27,6 +27,7 @@ macro_rules! message_struct { #[macro_export] macro_rules! streamable_struct { ($name:ident {$($field:ident: $t:ty $(,)? )*}) => { + #[wasm_patch::with_wasm] #[cfg_attr(feature = "py-bindings", pyo3::pyclass(get_all, frozen), derive(chia_py_streamable_macro::PyJsonDict, chia_py_streamable_macro::PyStreamable))] #[derive(Streamable, Hash, Debug, Clone, Eq, PartialEq)] #[cfg_attr(fuzzing, derive(arbitrary::Arbitrary))] @@ -34,28 +35,7 @@ macro_rules! streamable_struct { $(pub $field: $t),* } - #[cfg(not(feature = "py-bindings"))] - #[allow(clippy::too_many_arguments)] - impl $name { - pub fn new ( $($field: $t),* ) -> $name { - $name { $($field),* } - } - } - } -} - -#[macro_export] -macro_rules! streamable_struct2 { - ($name:ident {$($field:ident: $t:ty $(,)? )*}) => { - #[wasm_bindgen] - #[derive(Streamable, Hash, Debug, Clone, Eq, PartialEq)] - pub struct $name { - $( - #[wasm_bindgen] - pub $field: $t - ),* - } - + #[wasm_patch::with_wasm] #[cfg(not(feature = "py-bindings"))] #[allow(clippy::too_many_arguments)] impl $name { diff --git a/chia-protocol/src/program.rs b/chia-protocol/src/program.rs index 10bff1f1b..652cf35ae 100644 --- a/chia-protocol/src/program.rs +++ b/chia-protocol/src/program.rs @@ -17,6 +17,7 @@ use chia_py_streamable_macro::PyStreamable; #[cfg(feature = "py-bindings")] use pyo3::prelude::*; +#[wasm_patch::with_wasm] #[cfg_attr(feature = "py-bindings", pyclass, derive(PyStreamable))] #[derive(Hash, Debug, Clone, Eq, PartialEq)] pub struct Program(Bytes); diff --git a/wasm-patch/Cargo.toml b/wasm-patch/Cargo.toml new file mode 100644 index 000000000..9e210f55c --- /dev/null +++ b/wasm-patch/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "wasm-patch" +version = "0.1.0" +edition = "2021" + +[lib] +proc-macro = true + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +proc-macro2 = "1.0.70" +quote = "1.0.33" +syn = "2.0.39" diff --git a/wasm-patch/src/lib.rs b/wasm-patch/src/lib.rs new file mode 100644 index 000000000..98f55eea4 --- /dev/null +++ b/wasm-patch/src/lib.rs @@ -0,0 +1,33 @@ +extern crate proc_macro; + +use proc_macro::{TokenStream}; +use syn::{Item, parse_macro_input}; + +fn attach_wasm_bindgen(input: &TokenStream) -> TokenStream { + let mut t = input.to_string(); + t = format!("#[wasm_bindgen::prelude::wasm_bindgen] {}", t); + t.parse().unwrap() +} + +#[proc_macro_attribute] +pub fn with_wasm(_args: TokenStream, input: TokenStream) -> TokenStream { + let mut input_maybe_modified = input.clone(); + + let parsed_item = parse_macro_input!(input as Item); + + match parsed_item { + Item::Struct(_) => { + let shrink_u128 = true; + if shrink_u128 { + let mut s = input_maybe_modified.to_string(); + s = s.replace("u128", "u64"); + input_maybe_modified = s.parse().unwrap(); + } + // println!("{}", &input_maybe_modified); + attach_wasm_bindgen(&input_maybe_modified) + }, + _ => { + attach_wasm_bindgen(&input_maybe_modified) + } + } +} diff --git a/wasm/Cargo.toml b/wasm/Cargo.toml index 52e5e24bc..e420b3c5d 100644 --- a/wasm/Cargo.toml +++ b/wasm/Cargo.toml @@ -16,6 +16,7 @@ path = "src/lib.rs" [dependencies] chia = { path = ".." } +chia-protocol = { path = "../chia-protocol"} wasm-bindgen = "=0.2.88" wasm-bindgen-test = "=0.3.37" js-sys = "=0.3.64" From 634358b8ac5fbf8cdca7c81aa2d3369c924717e3 Mon Sep 17 00:00:00 2001 From: Izumi Hoshino Date: Fri, 1 Dec 2023 00:30:20 +0900 Subject: [PATCH 3/6] Checkpoint (wasm-bindgen success) --- chia-protocol/src/fullblock.rs | 8 ++++---- chia-protocol/src/header_block.rs | 8 ++++---- chia-protocol/src/reward_chain_block.rs | 6 +++--- chia-protocol/src/unfinished_block.rs | 4 ++-- chia-protocol/src/wallet_protocol.rs | 2 +- chia-protocol/src/weight_proof.rs | 2 +- chia-traits/src/from_json_dict.rs | 2 +- chia-traits/src/streamable.rs | 2 +- src/gen/conditions.rs | 10 +++++----- src/gen/run_puzzle.rs | 2 +- wasm-patch/src/lib.rs | 2 +- wheel/src/run_generator.rs | 4 ++-- 12 files changed, 26 insertions(+), 26 deletions(-) diff --git a/chia-protocol/src/fullblock.rs b/chia-protocol/src/fullblock.rs index 5003f3ba8..94f5ee2f2 100644 --- a/chia-protocol/src/fullblock.rs +++ b/chia-protocol/src/fullblock.rs @@ -43,7 +43,7 @@ impl FullBlock { self.foliage.foliage_transaction_block_hash.is_some() } - pub fn total_iters(&self) -> u128 { + pub fn total_iters(&self) -> u64 { self.reward_chain_block.total_iters } @@ -51,7 +51,7 @@ impl FullBlock { self.reward_chain_block.height } - pub fn weight(&self) -> u128 { + pub fn weight(&self) -> u64 { self.reward_chain_block.weight } @@ -112,7 +112,7 @@ impl FullBlock { #[getter] #[pyo3(name = "total_iters")] - fn py_total_iters(&self) -> u128 { + fn py_total_iters(&self) -> u64 { self.total_iters() } @@ -124,7 +124,7 @@ impl FullBlock { #[getter] #[pyo3(name = "weight")] - fn py_weight(&self) -> u128 { + fn py_weight(&self) -> u64 { self.weight() } diff --git a/chia-protocol/src/header_block.rs b/chia-protocol/src/header_block.rs index e5af72402..0f30af95e 100644 --- a/chia-protocol/src/header_block.rs +++ b/chia-protocol/src/header_block.rs @@ -45,7 +45,7 @@ impl HeaderBlock { self.reward_chain_block.height } - pub fn weight(&self) -> u128 { + pub fn weight(&self) -> u64 { self.reward_chain_block.weight } @@ -53,7 +53,7 @@ impl HeaderBlock { self.foliage.hash().into() } - pub fn total_iters(&self) -> u128 { + pub fn total_iters(&self) -> u64 { self.reward_chain_block.total_iters } @@ -100,7 +100,7 @@ impl HeaderBlock { #[getter] #[pyo3(name = "weight")] - fn py_weight(&self) -> u128 { + fn py_weight(&self) -> u64 { self.weight() } @@ -112,7 +112,7 @@ impl HeaderBlock { #[getter] #[pyo3(name = "total_iters")] - fn py_total_iters(&self) -> u128 { + fn py_total_iters(&self) -> u64 { self.total_iters() } diff --git a/chia-protocol/src/reward_chain_block.rs b/chia-protocol/src/reward_chain_block.rs index 89e0f75bb..8eb4f20b3 100644 --- a/chia-protocol/src/reward_chain_block.rs +++ b/chia-protocol/src/reward_chain_block.rs @@ -10,7 +10,7 @@ use chia_bls::G2Element; use pyo3::prelude::*; streamable_struct! (RewardChainBlockUnfinished { - total_iters: u128, + total_iters: u64, signage_point_index: u8, pos_ss_cc_challenge_hash: Bytes32, proof_of_space: ProofOfSpace, @@ -21,9 +21,9 @@ streamable_struct! (RewardChainBlockUnfinished { }); streamable_struct! (RewardChainBlock { - weight: u128, + weight: u64, height: u32, - total_iters: u128, + total_iters: u64, signage_point_index: u8, pos_ss_cc_challenge_hash: Bytes32, proof_of_space: ProofOfSpace, diff --git a/chia-protocol/src/unfinished_block.rs b/chia-protocol/src/unfinished_block.rs index 16e2560a4..2595ccad7 100644 --- a/chia-protocol/src/unfinished_block.rs +++ b/chia-protocol/src/unfinished_block.rs @@ -38,7 +38,7 @@ impl UnfinishedBlock { self.foliage.foliage_transaction_block_hash.is_some() } - pub fn total_iters(&self) -> u128 { + pub fn total_iters(&self) -> u64 { self.reward_chain_block.total_iters } } @@ -65,7 +65,7 @@ impl UnfinishedBlock { #[getter] #[pyo3(name = "total_iters")] - fn py_total_iters(&self) -> u128 { + fn py_total_iters(&self) -> u64 { self.total_iters() } } diff --git a/chia-protocol/src/wallet_protocol.rs b/chia-protocol/src/wallet_protocol.rs index 973924c60..85d853cc3 100644 --- a/chia-protocol/src/wallet_protocol.rs +++ b/chia-protocol/src/wallet_protocol.rs @@ -45,7 +45,7 @@ message_struct! (TransactionAck { message_struct!(NewPeakWallet { header_hash: Bytes32, height: u32, - weight: u128, + weight: u64, fork_point_with_previous_peak: u32, }); diff --git a/chia-protocol/src/weight_proof.rs b/chia-protocol/src/weight_proof.rs index e6eafb2f7..88b55440f 100644 --- a/chia-protocol/src/weight_proof.rs +++ b/chia-protocol/src/weight_proof.rs @@ -17,7 +17,7 @@ streamable_struct! (SubSlotData { icc_slot_end_info: Option, cc_ip_vdf_info: Option, icc_ip_vdf_info: Option, - total_iters: Option, + total_iters: Option, }); #[cfg(feature = "py-bindings")] diff --git a/chia-traits/src/from_json_dict.rs b/chia-traits/src/from_json_dict.rs index 17e055873..2a14bf5a6 100644 --- a/chia-traits/src/from_json_dict.rs +++ b/chia-traits/src/from_json_dict.rs @@ -39,7 +39,7 @@ from_json_primitive!(u32); from_json_primitive!(i32); from_json_primitive!(u64); from_json_primitive!(i64); -from_json_primitive!(u128); +from_json_primitive!(u64); from_json_primitive!(i128); from_json_primitive!(String); diff --git a/chia-traits/src/streamable.rs b/chia-traits/src/streamable.rs index c7338c447..6d297d90b 100644 --- a/chia-traits/src/streamable.rs +++ b/chia-traits/src/streamable.rs @@ -313,7 +313,7 @@ fn test_parse_u64() { } #[test] -fn test_parse_u128() { +fn test_parse_u64() { from_bytes::(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 0); from_bytes::(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], 1); from_bytes::( diff --git a/src/gen/conditions.rs b/src/gen/conditions.rs index 67fc9433b..36df61a57 100644 --- a/src/gen/conditions.rs +++ b/src/gen/conditions.rs @@ -683,10 +683,10 @@ pub struct SpendBundleConditions { pub cost: u64, // the sum of all values of all spent coins - pub removal_amount: u128, + pub removal_amount: u64, // the sum of all amounts of CREATE_COIN conditions - pub addition_amount: u128, + pub addition_amount: u64, } #[derive(Default)] @@ -787,7 +787,7 @@ pub fn process_single_spend( state.spent_puzzles.insert(puzzle_hash); - ret.removal_amount += my_amount as u128; + ret.removal_amount += my_amount as u64; let mut spend = Spend::new(parent_id, my_amount, puzzle_hash, coin_id); @@ -898,7 +898,7 @@ pub fn parse_conditions( if !spend.create_coin.insert(new_coin) { return Err(ValidationErr(c, ErrorCode::DuplicateOutput)); } - ret.addition_amount += amount as u128; + ret.addition_amount += amount as u64; } Condition::AssertSecondsRelative(s) => { // keep the most strict condition. i.e. the highest limit @@ -1194,7 +1194,7 @@ pub fn validate_conditions( return Err(ValidationErr(spends, ErrorCode::MintingCoin)); } - if ret.removal_amount - ret.addition_amount < ret.reserve_fee as u128 { + if ret.removal_amount - ret.addition_amount < ret.reserve_fee as u64 { // the actual fee is lower than the reserved fee return Err(ValidationErr(spends, ErrorCode::ReserveFeeConditionFailed)); } diff --git a/src/gen/run_puzzle.rs b/src/gen/run_puzzle.rs index 4ee5a79d6..46d196554 100644 --- a/src/gen/run_puzzle.rs +++ b/src/gen/run_puzzle.rs @@ -33,7 +33,7 @@ pub fn run_puzzle( let Reduction(clvm_cost, conditions) = run_program(a, &dialect, puzzle, solution, max_cost)?; let mut ret = SpendBundleConditions { - removal_amount: amount as u128, + removal_amount: amount as u64, ..Default::default() }; let mut state = ParseState::default(); diff --git a/wasm-patch/src/lib.rs b/wasm-patch/src/lib.rs index 98f55eea4..ebf1aed7f 100644 --- a/wasm-patch/src/lib.rs +++ b/wasm-patch/src/lib.rs @@ -5,7 +5,7 @@ use syn::{Item, parse_macro_input}; fn attach_wasm_bindgen(input: &TokenStream) -> TokenStream { let mut t = input.to_string(); - t = format!("#[wasm_bindgen::prelude::wasm_bindgen] {}", t); + t = format!("#[wasm_bindgen::prelude::wasm_bindgen(getter_with_clone)] {}", t); t.parse().unwrap() } diff --git a/wheel/src/run_generator.rs b/wheel/src/run_generator.rs index 57e93afd9..3b578a535 100644 --- a/wheel/src/run_generator.rs +++ b/wheel/src/run_generator.rs @@ -60,9 +60,9 @@ pub struct PySpendBundleConditions { pub agg_sig_unsafe: Vec<(Bytes48, Bytes)>, pub cost: u64, // the sum of all values of all spent coins - pub removal_amount: u128, + pub removal_amount: u64, // the sum of all amounts of CREATE_COIN conditions - pub addition_amount: u128, + pub addition_amount: u64, } fn convert_agg_sigs(a: &Allocator, agg_sigs: &[(NodePtr, NodePtr)]) -> Vec<(Bytes48, Bytes)> { From d5c47688c33533df56269017b655ba8291fc4ce3 Mon Sep 17 00:00:00 2001 From: Izumi Hoshino Date: Mon, 4 Dec 2023 23:42:12 +0900 Subject: [PATCH 4/6] Made u128 -> u64 conversion clearer --- chia-protocol/src/vdf.rs | 2 +- wasm-patch/Cargo.toml | 2 +- wasm-patch/src/lib.rs | 50 ++++++++++++++++++++++------------------ 3 files changed, 30 insertions(+), 24 deletions(-) diff --git a/chia-protocol/src/vdf.rs b/chia-protocol/src/vdf.rs index c1e950f67..bb5bb0386 100644 --- a/chia-protocol/src/vdf.rs +++ b/chia-protocol/src/vdf.rs @@ -6,7 +6,7 @@ use crate::{Bytes, Bytes32}; streamable_struct!(VDFInfo { challenge: Bytes32, - number_of_iterations: u64, + number_of_iterations: u128, output: ClassgroupElement, }); diff --git a/wasm-patch/Cargo.toml b/wasm-patch/Cargo.toml index 9e210f55c..2903cdf55 100644 --- a/wasm-patch/Cargo.toml +++ b/wasm-patch/Cargo.toml @@ -11,4 +11,4 @@ proc-macro = true [dependencies] proc-macro2 = "1.0.70" quote = "1.0.33" -syn = "2.0.39" +syn = { version = "2.0.39", features = ["full", "visit-mut"]} diff --git a/wasm-patch/src/lib.rs b/wasm-patch/src/lib.rs index ebf1aed7f..7c1f339d3 100644 --- a/wasm-patch/src/lib.rs +++ b/wasm-patch/src/lib.rs @@ -1,33 +1,39 @@ extern crate proc_macro; +use syn::{visit_mut::VisitMut, parse_quote, Type}; use proc_macro::{TokenStream}; -use syn::{Item, parse_macro_input}; -fn attach_wasm_bindgen(input: &TokenStream) -> TokenStream { - let mut t = input.to_string(); - t = format!("#[wasm_bindgen::prelude::wasm_bindgen(getter_with_clone)] {}", t); - t.parse().unwrap() +// See https://github.com/rustwasm/wasm-bindgen/issues/3707 +fn _patch_issue_3707(input: &TokenStream) -> TokenStream { + let mut s = input.to_string(); + s = format!("#[wasm_bindgen::prelude::wasm_bindgen(getter_with_clone)] {}", s); + s.parse().unwrap() } -#[proc_macro_attribute] -pub fn with_wasm(_args: TokenStream, input: TokenStream) -> TokenStream { - let mut input_maybe_modified = input.clone(); +struct TypeConverter; - let parsed_item = parse_macro_input!(input as Item); - - match parsed_item { - Item::Struct(_) => { - let shrink_u128 = true; - if shrink_u128 { - let mut s = input_maybe_modified.to_string(); - s = s.replace("u128", "u64"); - input_maybe_modified = s.parse().unwrap(); +// As of Dec 2023, wasm-bindgen cannot handle u128 at all. +// We convert u128 into u64 here. +// u64 is then converted into bigint in JS which has no size limitation. +// So this conversion does no harm unless a value greater than u64_max is +// communicated between JS and Wasm Runtime. +impl VisitMut for TypeConverter { + fn visit_type_mut(&mut self, i: &mut Type) { + if let Type::Path(type_path) = i { + if type_path.path.is_ident("u128") { + *i = parse_quote! { u64 }; } - // println!("{}", &input_maybe_modified); - attach_wasm_bindgen(&input_maybe_modified) - }, - _ => { - attach_wasm_bindgen(&input_maybe_modified) } + syn::visit_mut::visit_type_mut(self, i); } } + +#[proc_macro_attribute] +pub fn with_wasm(_args: TokenStream, input: TokenStream) -> TokenStream { + let mut ast: syn::File = syn::parse(input.into()).unwrap(); + let mut converter = TypeConverter; + converter.visit_file_mut(&mut ast); + + let input_maybe_modified = quote::quote!(#ast); + _patch_issue_3707(&input_maybe_modified.into()) +} From 34b56a45e3edb77839f2a9ea27e039f06c405a53 Mon Sep 17 00:00:00 2001 From: Izumi Hoshino Date: Wed, 31 Jan 2024 00:27:32 +0900 Subject: [PATCH 5/6] Clean up code --- chia-bls/src/gtelement.rs | 2 +- chia-bls/src/public_key.rs | 2 +- chia-bls/src/secret_key.rs | 2 +- chia-bls/src/signature.rs | 2 +- chia-protocol/src/bytes.rs | 68 +++++++++++++++++-------- chia-protocol/src/chia_protocol.rs | 4 +- chia-protocol/src/fullblock.rs | 10 ++-- chia-protocol/src/header_block.rs | 10 ++-- chia-protocol/src/message_struct.rs | 4 +- chia-protocol/src/program.rs | 2 +- chia-protocol/src/reward_chain_block.rs | 6 +-- chia-protocol/src/unfinished_block.rs | 5 +- chia-protocol/src/vdf.rs | 2 +- chia-protocol/src/wallet_protocol.rs | 2 +- chia-protocol/src/weight_proof.rs | 2 +- chia-traits/src/from_json_dict.rs | 2 +- chia-traits/src/streamable.rs | 2 +- src/gen/conditions.rs | 10 ++-- src/gen/run_puzzle.rs | 2 +- wasm-patch/src/lib.rs | 9 ++++ wheel/src/run_generator.rs | 4 +- 21 files changed, 95 insertions(+), 57 deletions(-) diff --git a/chia-bls/src/gtelement.rs b/chia-bls/src/gtelement.rs index 18112db10..68bd1d84f 100644 --- a/chia-bls/src/gtelement.rs +++ b/chia-bls/src/gtelement.rs @@ -19,7 +19,7 @@ use pyo3::exceptions::PyValueError; #[cfg(feature = "py-bindings")] use pyo3::{pyclass, pymethods, IntoPy, PyAny, PyObject, PyResult, Python}; -#[wasm_patch::with_wasm] +#[cfg_attr(target_arch = "wasm32", wasm_patch::with_wasm)] #[cfg_attr(feature = "py-bindings", pyclass, derive(PyStreamable, Clone))] pub struct GTElement(pub(crate) blst_fp12); diff --git a/chia-bls/src/public_key.rs b/chia-bls/src/public_key.rs index 7798f601b..afad363c3 100644 --- a/chia-bls/src/public_key.rs +++ b/chia-bls/src/public_key.rs @@ -22,7 +22,7 @@ use chia_traits::to_json_dict::ToJsonDict; #[cfg(feature = "py-bindings")] use pyo3::{pyclass, pymethods, IntoPy, PyAny, PyObject, PyResult, Python}; -#[wasm_patch::with_wasm] +#[cfg_attr(target_arch = "wasm32", wasm_patch::with_wasm)] #[cfg_attr( feature = "py-bindings", pyclass(name = "G1Element"), diff --git a/chia-bls/src/secret_key.rs b/chia-bls/src/secret_key.rs index 26996d29a..342f8ea01 100644 --- a/chia-bls/src/secret_key.rs +++ b/chia-bls/src/secret_key.rs @@ -22,7 +22,7 @@ use chia_traits::to_json_dict::ToJsonDict; #[cfg(feature = "py-bindings")] use pyo3::{pyclass, pymethods, IntoPy, PyAny, PyObject, PyResult, Python}; -#[wasm_patch::with_wasm] +#[cfg_attr(target_arch = "wasm32", wasm_patch::with_wasm)] #[cfg_attr( feature = "py-bindings", pyclass(frozen, name = "PrivateKey"), diff --git a/chia-bls/src/signature.rs b/chia-bls/src/signature.rs index 8f0725573..554f73698 100644 --- a/chia-bls/src/signature.rs +++ b/chia-bls/src/signature.rs @@ -26,7 +26,7 @@ use pyo3::{pyclass, pymethods, IntoPy, PyAny, PyObject, PyResult, Python}; // we use the augmented scheme pub const DST: &[u8] = b"BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_AUG_"; -#[wasm_patch::with_wasm] +#[cfg_attr(target_arch = "wasm32", wasm_patch::with_wasm)] #[cfg_attr( feature = "py-bindings", pyclass(name = "G2Element"), diff --git a/chia-protocol/src/bytes.rs b/chia-protocol/src/bytes.rs index 79e71d82f..1f19d9102 100644 --- a/chia-protocol/src/bytes.rs +++ b/chia-protocol/src/bytes.rs @@ -12,7 +12,9 @@ use std::fmt::Debug; use std::io::Cursor; use std::ops::Deref; +#[cfg(target_arch = "wasm32")] use wasm_bindgen::prelude::*; +#[cfg(target_arch = "wasm32")] use paste::paste; #[cfg(feature = "py-bindings")] @@ -191,11 +193,11 @@ impl fmt::Display for Bytes { #[cfg_attr(fuzzing, derive(arbitrary::Arbitrary))] pub struct BytesImpl([u8; N]); +#[cfg(target_arch = "wasm32")] macro_rules! generate_bytes_n { ($($N:expr),+) => { paste! { $( - #[cfg(target_arch = "wasm32")] #[wasm_bindgen] #[derive(Hash, PartialEq, Eq, Copy, Clone, PartialOrd, Ord)] #[cfg_attr(fuzzing, derive(arbitrary::Arbitrary))] @@ -204,6 +206,7 @@ macro_rules! generate_bytes_n { } }; } +#[cfg(target_arch = "wasm32")] generate_bytes_n!(32, 48, 96, 100); impl Streamable for BytesImpl { @@ -220,11 +223,11 @@ impl Streamable for BytesImpl { } } +#[cfg(target_arch = "wasm32")] macro_rules! impl_streamable_for_bytes_n { ($($N:expr),+) => { paste! { $( - #[cfg(target_arch = "wasm32")] impl Streamable for [] { fn update_digest(&self, digest: &mut Sha256) { digest.update(self.0); @@ -242,6 +245,7 @@ macro_rules! impl_streamable_for_bytes_n { } }; } +#[cfg(target_arch = "wasm32")] impl_streamable_for_bytes_n!(32, 48, 96, 100); impl ToClvm for BytesImpl { @@ -250,11 +254,11 @@ impl ToClvm for BytesImpl { } } +#[cfg(target_arch = "wasm32")] macro_rules! impl_to_clvm_for_bytes_n { ($($N:expr),+) => { paste! { $( - #[cfg(target_arch = "wasm32")] impl ToClvm for [] { fn to_clvm(&self, a: &mut Allocator) -> clvm_traits::Result { Ok(a.new_atom(self.0.as_slice())?) @@ -264,6 +268,7 @@ macro_rules! impl_to_clvm_for_bytes_n { } }; } +#[cfg(target_arch = "wasm32")] impl_to_clvm_for_bytes_n!(32, 48, 96, 100); impl FromClvm for BytesImpl { @@ -283,11 +288,11 @@ impl FromClvm for BytesImpl { } } +#[cfg(target_arch = "wasm32")] macro_rules! impl_from_clvm_for_bytes_n { ($($N:expr),+) => { paste! { $( - #[cfg(target_arch = "wasm32")] impl FromClvm for [] { fn from_clvm(a: &Allocator, ptr: NodePtr) -> clvm_traits::Result { let blob = match a.sexp(ptr) { @@ -308,6 +313,7 @@ macro_rules! impl_from_clvm_for_bytes_n { } }; } +#[cfg(target_arch = "wasm32")] impl_from_clvm_for_bytes_n!(32, 48, 96, 100); impl From<[u8; N]> for BytesImpl { @@ -316,11 +322,11 @@ impl From<[u8; N]> for BytesImpl { } } +#[cfg(target_arch = "wasm32")] macro_rules! impl_from_u8n_for_bytes_n { ($($N:expr),+) => { paste! { $( - #[cfg(target_arch = "wasm32")] impl From<[u8; $N]> for [] { fn from(v: [u8; $N]) -> [] { [](v) @@ -330,6 +336,7 @@ macro_rules! impl_from_u8n_for_bytes_n { } }; } +#[cfg(target_arch = "wasm32")] impl_from_u8n_for_bytes_n!(32, 48, 96, 100); impl From<&[u8; N]> for BytesImpl { @@ -338,11 +345,11 @@ impl From<&[u8; N]> for BytesImpl { } } +#[cfg(target_arch = "wasm32")] macro_rules! impl_from_ref_u8n_for_bytes_n { ($($N:expr),+) => { paste! { $( - #[cfg(target_arch = "wasm32")] impl From<&[u8; $N]> for [] { fn from(v: &[u8; $N]) -> [] { [](*v) @@ -352,6 +359,7 @@ macro_rules! impl_from_ref_u8n_for_bytes_n { } }; } +#[cfg(target_arch = "wasm32")] impl_from_ref_u8n_for_bytes_n!(32, 48, 96, 100); impl From<&[u8]> for BytesImpl { @@ -365,11 +373,11 @@ impl From<&[u8]> for BytesImpl { } } +#[cfg(target_arch = "wasm32")] macro_rules! impl_from_ref_u8_for_bytes_n { ($($N:expr),+) => { paste! { $( - #[cfg(target_arch = "wasm32")] impl From<&[u8]> for [] { fn from(v: &[u8]) -> [] { if v.len() != $N { @@ -384,6 +392,7 @@ macro_rules! impl_from_ref_u8_for_bytes_n { } }; } +#[cfg(target_arch = "wasm32")] impl_from_ref_u8_for_bytes_n!(32, 48, 96, 100); impl From<&Vec> for BytesImpl { @@ -397,11 +406,11 @@ impl From<&Vec> for BytesImpl { } } +#[cfg(target_arch = "wasm32")] macro_rules! impl_from_ref_vec_u8_for_bytes_n { ($($N:expr),+) => { paste! { $( - #[cfg(target_arch = "wasm32")] impl From<&Vec> for [] { fn from(v: &Vec) -> [] { if v.len() != $N { @@ -416,6 +425,7 @@ macro_rules! impl_from_ref_vec_u8_for_bytes_n { } }; } +#[cfg(target_arch = "wasm32")] impl_from_ref_vec_u8_for_bytes_n!(32, 48, 96, 100); impl<'a, const N: usize> From<&'a BytesImpl> for &'a [u8; N] { @@ -424,11 +434,11 @@ impl<'a, const N: usize> From<&'a BytesImpl> for &'a [u8; N] { } } +#[cfg(target_arch = "wasm32")] macro_rules! impl_from_a_bytes_u8_for_a_u8n { ($($N:expr),+) => { paste! { $( - #[cfg(target_arch = "wasm32")] impl<'a> From<&'a []> for &'a [u8; $N] { fn from(v: &'a []) -> &'a [u8; $N] { &v.0 @@ -438,6 +448,7 @@ macro_rules! impl_from_a_bytes_u8_for_a_u8n { } }; } +#[cfg(target_arch = "wasm32")] impl_from_a_bytes_u8_for_a_u8n!(32, 48, 96, 100); impl From<&BytesImpl> for [u8; N] { @@ -446,11 +457,11 @@ impl From<&BytesImpl> for [u8; N] { } } +#[cfg(target_arch = "wasm32")] macro_rules! impl_from_ref_bytes_n_for_u8n { ($($N:expr),+) => { paste! { $( - #[cfg(target_arch = "wasm32")] impl From<&[]> for [u8; $N] { fn from(v: &[]) -> [u8; $N] { v.0 @@ -460,6 +471,7 @@ macro_rules! impl_from_ref_bytes_n_for_u8n { } }; } +#[cfg(target_arch = "wasm32")] impl_from_ref_bytes_n_for_u8n!(32, 48, 96, 100); impl<'a, const N: usize> From<&'a BytesImpl> for &'a [u8] { @@ -467,11 +479,11 @@ impl<'a, const N: usize> From<&'a BytesImpl> for &'a [u8] { &v.0 } } +#[cfg(target_arch = "wasm32")] macro_rules! impl_from_a_bytes_n_for_a_u8 { ($($N:expr),+) => { paste! { $( - #[cfg(target_arch = "wasm32")] impl<'a> From<&'a []> for &'a [u8] { fn from(v: &'a []) -> &'a [u8] { &v.0 @@ -481,6 +493,7 @@ macro_rules! impl_from_a_bytes_n_for_a_u8 { } }; } +#[cfg(target_arch = "wasm32")] impl_from_a_bytes_n_for_a_u8!(32, 48, 96, 100); impl BytesImpl { @@ -488,11 +501,11 @@ impl BytesImpl { self.0.to_vec() } } +#[cfg(target_arch = "wasm32")] macro_rules! impl_bytes_n { ($($N:expr),+) => { paste! { $( - #[cfg(target_arch = "wasm32")] impl [] { pub fn to_vec(&self) -> Vec { self.0.to_vec() @@ -502,6 +515,7 @@ macro_rules! impl_bytes_n { } }; } +#[cfg(target_arch = "wasm32")] impl_bytes_n!(32, 48, 96, 100); impl AsRef<[u8]> for BytesImpl { @@ -510,11 +524,11 @@ impl AsRef<[u8]> for BytesImpl { } } +#[cfg(target_arch = "wasm32")] macro_rules! impl_as_ref_for_bytes_n { ($($N:expr),+) => { paste! { $( - #[cfg(target_arch = "wasm32")] impl AsRef<[u8]> for [] { fn as_ref(&self) -> &[u8] { &self.0 } } @@ -522,6 +536,7 @@ macro_rules! impl_as_ref_for_bytes_n { } }; } +#[cfg(target_arch = "wasm32")] impl_as_ref_for_bytes_n!(32, 48, 96, 100); impl Deref for BytesImpl { @@ -531,11 +546,11 @@ impl Deref for BytesImpl { } } +#[cfg(target_arch = "wasm32")] macro_rules! impl_deref_for_bytes_n { ($($N:expr),+) => { paste! { $( - #[cfg(target_arch = "wasm32")] impl Deref for [] { type Target = [u8]; fn deref(&self) -> &[u8] { &self.0 } @@ -544,6 +559,7 @@ macro_rules! impl_deref_for_bytes_n { } }; } +#[cfg(target_arch = "wasm32")] impl_deref_for_bytes_n!(32, 48, 96, 100); impl Debug for BytesImpl { @@ -552,11 +568,11 @@ impl Debug for BytesImpl { } } +#[cfg(target_arch = "wasm32")] macro_rules! impl_debug_for_bytes_n { ($($N:expr),+) => { paste! { $( - #[cfg(target_arch = "wasm32")] impl Debug for [] { fn fmt(&self, formatter: &mut Formatter<'_>) -> std::result::Result<(), std::fmt::Error> { formatter.write_str(&hex::encode(self.0)) @@ -566,6 +582,7 @@ macro_rules! impl_debug_for_bytes_n { } }; } +#[cfg(target_arch = "wasm32")] impl_debug_for_bytes_n!(32, 48, 96, 100); impl fmt::Display for BytesImpl { @@ -574,11 +591,11 @@ impl fmt::Display for BytesImpl { } } +#[cfg(target_arch = "wasm32")] macro_rules! impl_display_for_bytes_n { ($($N:expr),+) => { paste! { $( - #[cfg(target_arch = "wasm32")] impl fmt::Display for [] { fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str(&hex::encode(self.0)) @@ -588,6 +605,7 @@ macro_rules! impl_display_for_bytes_n { } }; } +#[cfg(target_arch = "wasm32")] impl_display_for_bytes_n!(32, 48, 96, 100); impl PartialEq<&[u8]> for BytesImpl { @@ -596,11 +614,11 @@ impl PartialEq<&[u8]> for BytesImpl { } } +#[cfg(target_arch = "wasm32")] macro_rules! impl_partial_eq_for_ref_bytes_n { ($($N:expr),+) => { paste! { $( - #[cfg(target_arch = "wasm32")] impl PartialEq<&[u8]> for [] { fn eq(&self, lhs: &&[u8]) -> bool { self.0 == *lhs } } @@ -608,6 +626,7 @@ macro_rules! impl_partial_eq_for_ref_bytes_n { } }; } +#[cfg(target_arch = "wasm32")] impl_partial_eq_for_ref_bytes_n!(32, 48, 96, 100); impl PartialEq> for &[u8] { @@ -616,11 +635,11 @@ impl PartialEq> for &[u8] { } } +#[cfg(target_arch = "wasm32")] macro_rules! impl_partial_eq_for_ref_u8 { ($($N:expr),+) => { paste! { $( - #[cfg(target_arch = "wasm32")] impl PartialEq<[]> for &[u8] { fn eq(&self, lhs: &[]) -> bool { self == &lhs.0 } } @@ -628,6 +647,7 @@ macro_rules! impl_partial_eq_for_ref_u8 { } }; } +#[cfg(target_arch = "wasm32")] impl_partial_eq_for_ref_u8!(32, 48, 96, 100); impl PartialEq<&[u8; N]> for BytesImpl { @@ -636,11 +656,11 @@ impl PartialEq<&[u8; N]> for BytesImpl { } } +#[cfg(target_arch = "wasm32")] macro_rules! impl_partial_eq_ref_u8n_for_bytes_n { ($($N:expr),+) => { paste! { $( - #[cfg(target_arch = "wasm32")] impl PartialEq<&[u8; $N]> for [] { fn eq(&self, lhs: &&[u8; $N]) -> bool { &self.0 == *lhs } } @@ -648,6 +668,7 @@ macro_rules! impl_partial_eq_ref_u8n_for_bytes_n { } }; } +#[cfg(target_arch = "wasm32")] impl_partial_eq_ref_u8n_for_bytes_n!(32, 48, 96, 100); impl PartialEq> for &[u8; N] { @@ -656,11 +677,11 @@ impl PartialEq> for &[u8; N] { } } +#[cfg(target_arch = "wasm32")] macro_rules! impl_partial_eq_bytes_n_for_ref_u8n { ($($N:expr),+) => { paste! { $( - #[cfg(target_arch = "wasm32")] impl PartialEq<[]> for &[u8; $N] { fn eq(&self, lhs: &[]) -> bool { *self == &lhs.0 } } @@ -668,6 +689,7 @@ macro_rules! impl_partial_eq_bytes_n_for_ref_u8n { } }; } +#[cfg(target_arch = "wasm32")] impl_partial_eq_bytes_n_for_ref_u8n!(32, 48, 96, 100); impl PartialEq<[u8; N]> for BytesImpl { @@ -676,11 +698,11 @@ impl PartialEq<[u8; N]> for BytesImpl { } } +#[cfg(target_arch = "wasm32")] macro_rules! impl_partial_eq_u8n_for_bytes_n { ($($N:expr),+) => { paste! { $( - #[cfg(target_arch = "wasm32")] impl PartialEq<[u8; $N]> for [] { fn eq(&self, lhs: &[u8; $N]) -> bool { &self.0 == lhs @@ -690,6 +712,7 @@ macro_rules! impl_partial_eq_u8n_for_bytes_n { } }; } +#[cfg(target_arch = "wasm32")] impl_partial_eq_u8n_for_bytes_n!(32, 48, 96, 100); @@ -699,11 +722,11 @@ impl PartialEq> for [u8; N] { } } +#[cfg(target_arch = "wasm32")] macro_rules! impl_partial_eq_bytes_n_for_u8n { ($($N:expr),+) => { paste! { $( - #[cfg(target_arch = "wasm32")] impl PartialEq<[]> for [u8; $N] { fn eq(&self, lhs: &[]) -> bool { self == &lhs.0 } } @@ -711,6 +734,7 @@ macro_rules! impl_partial_eq_bytes_n_for_u8n { } }; } +#[cfg(target_arch = "wasm32")] impl_partial_eq_bytes_n_for_u8n!(32, 48, 96, 100); #[cfg(feature = "py-bindings")] diff --git a/chia-protocol/src/chia_protocol.rs b/chia-protocol/src/chia_protocol.rs index 663c8c860..c894b1e67 100644 --- a/chia-protocol/src/chia_protocol.rs +++ b/chia-protocol/src/chia_protocol.rs @@ -7,7 +7,7 @@ use crate::Bytes; #[cfg(feature = "py-bindings")] use chia_py_streamable_macro::{PyJsonDict, PyStreamable}; -#[wasm_patch::with_wasm] +#[cfg_attr(target_arch = "wasm32", wasm_patch::with_wasm)] #[repr(u8)] #[cfg_attr(feature = "py-bindings", derive(PyJsonDict, PyStreamable))] #[cfg_attr(fuzzing, derive(arbitrary::Arbitrary))] @@ -128,7 +128,7 @@ pub trait ChiaProtocolMessage { fn msg_type() -> ProtocolMessageTypes; } -#[wasm_patch::with_wasm] +#[cfg_attr(target_arch = "wasm32", wasm_patch::with_wasm)] #[repr(u8)] #[cfg_attr(feature = "py-bindings", derive(PyJsonDict, PyStreamable))] #[cfg_attr(fuzzing, derive(arbitrary::Arbitrary))] diff --git a/chia-protocol/src/fullblock.rs b/chia-protocol/src/fullblock.rs index 94f5ee2f2..302ce0d52 100644 --- a/chia-protocol/src/fullblock.rs +++ b/chia-protocol/src/fullblock.rs @@ -43,7 +43,8 @@ impl FullBlock { self.foliage.foliage_transaction_block_hash.is_some() } - pub fn total_iters(&self) -> u64 { + #[cfg_attr(target_arch = "wasm32", wasm_patch::conv_u128_to_u64_for_wasm)] + pub fn total_iters(&self) -> u128 { self.reward_chain_block.total_iters } @@ -51,7 +52,8 @@ impl FullBlock { self.reward_chain_block.height } - pub fn weight(&self) -> u64 { + #[cfg_attr(target_arch = "wasm32", wasm_patch::conv_u128_to_u64_for_wasm)] + pub fn weight(&self) -> u128 { self.reward_chain_block.weight } @@ -112,7 +114,7 @@ impl FullBlock { #[getter] #[pyo3(name = "total_iters")] - fn py_total_iters(&self) -> u64 { + fn py_total_iters(&self) -> u128 { self.total_iters() } @@ -124,7 +126,7 @@ impl FullBlock { #[getter] #[pyo3(name = "weight")] - fn py_weight(&self) -> u64 { + fn py_weight(&self) -> u128 { self.weight() } diff --git a/chia-protocol/src/header_block.rs b/chia-protocol/src/header_block.rs index 0f30af95e..c4aa92044 100644 --- a/chia-protocol/src/header_block.rs +++ b/chia-protocol/src/header_block.rs @@ -45,7 +45,8 @@ impl HeaderBlock { self.reward_chain_block.height } - pub fn weight(&self) -> u64 { + #[cfg_attr(target_arch = "wasm32", wasm_patch::conv_u128_to_u64_for_wasm)] + pub fn weight(&self) -> u128 { self.reward_chain_block.weight } @@ -53,7 +54,8 @@ impl HeaderBlock { self.foliage.hash().into() } - pub fn total_iters(&self) -> u64 { + #[cfg_attr(target_arch = "wasm32", wasm_patch::conv_u128_to_u64_for_wasm)] + pub fn total_iters(&self) -> u128 { self.reward_chain_block.total_iters } @@ -100,7 +102,7 @@ impl HeaderBlock { #[getter] #[pyo3(name = "weight")] - fn py_weight(&self) -> u64 { + fn py_weight(&self) -> u128 { self.weight() } @@ -112,7 +114,7 @@ impl HeaderBlock { #[getter] #[pyo3(name = "total_iters")] - fn py_total_iters(&self) -> u64 { + fn py_total_iters(&self) -> u128 { self.total_iters() } diff --git a/chia-protocol/src/message_struct.rs b/chia-protocol/src/message_struct.rs index d6d267653..aa4154370 100644 --- a/chia-protocol/src/message_struct.rs +++ b/chia-protocol/src/message_struct.rs @@ -27,7 +27,7 @@ macro_rules! message_struct { #[macro_export] macro_rules! streamable_struct { ($name:ident {$($field:ident: $t:ty $(,)? )*}) => { - #[wasm_patch::with_wasm] + #[cfg_attr(target_arch = "wasm32", wasm_patch::with_wasm)] #[cfg_attr(feature = "py-bindings", pyo3::pyclass(get_all, frozen), derive(chia_py_streamable_macro::PyJsonDict, chia_py_streamable_macro::PyStreamable))] #[derive(Streamable, Hash, Debug, Clone, Eq, PartialEq)] #[cfg_attr(fuzzing, derive(arbitrary::Arbitrary))] @@ -35,7 +35,7 @@ macro_rules! streamable_struct { $(pub $field: $t),* } - #[wasm_patch::with_wasm] + #[cfg_attr(target_arch = "wasm32", wasm_patch::with_wasm)] #[cfg(not(feature = "py-bindings"))] #[allow(clippy::too_many_arguments)] impl $name { diff --git a/chia-protocol/src/program.rs b/chia-protocol/src/program.rs index 652cf35ae..b752c0a7b 100644 --- a/chia-protocol/src/program.rs +++ b/chia-protocol/src/program.rs @@ -17,7 +17,7 @@ use chia_py_streamable_macro::PyStreamable; #[cfg(feature = "py-bindings")] use pyo3::prelude::*; -#[wasm_patch::with_wasm] +#[cfg_attr(target_arch = "wasm32", wasm_patch::with_wasm)] #[cfg_attr(feature = "py-bindings", pyclass, derive(PyStreamable))] #[derive(Hash, Debug, Clone, Eq, PartialEq)] pub struct Program(Bytes); diff --git a/chia-protocol/src/reward_chain_block.rs b/chia-protocol/src/reward_chain_block.rs index 8eb4f20b3..89e0f75bb 100644 --- a/chia-protocol/src/reward_chain_block.rs +++ b/chia-protocol/src/reward_chain_block.rs @@ -10,7 +10,7 @@ use chia_bls::G2Element; use pyo3::prelude::*; streamable_struct! (RewardChainBlockUnfinished { - total_iters: u64, + total_iters: u128, signage_point_index: u8, pos_ss_cc_challenge_hash: Bytes32, proof_of_space: ProofOfSpace, @@ -21,9 +21,9 @@ streamable_struct! (RewardChainBlockUnfinished { }); streamable_struct! (RewardChainBlock { - weight: u64, + weight: u128, height: u32, - total_iters: u64, + total_iters: u128, signage_point_index: u8, pos_ss_cc_challenge_hash: Bytes32, proof_of_space: ProofOfSpace, diff --git a/chia-protocol/src/unfinished_block.rs b/chia-protocol/src/unfinished_block.rs index 2595ccad7..fd2d428e5 100644 --- a/chia-protocol/src/unfinished_block.rs +++ b/chia-protocol/src/unfinished_block.rs @@ -38,7 +38,8 @@ impl UnfinishedBlock { self.foliage.foliage_transaction_block_hash.is_some() } - pub fn total_iters(&self) -> u64 { + #[cfg_attr(target_arch = "wasm32", wasm_patch::conv_u128_to_u64_for_wasm)] + pub fn total_iters(&self) -> u128 { self.reward_chain_block.total_iters } } @@ -65,7 +66,7 @@ impl UnfinishedBlock { #[getter] #[pyo3(name = "total_iters")] - fn py_total_iters(&self) -> u64 { + fn py_total_iters(&self) -> u128 { self.total_iters() } } diff --git a/chia-protocol/src/vdf.rs b/chia-protocol/src/vdf.rs index bb5bb0386..c1e950f67 100644 --- a/chia-protocol/src/vdf.rs +++ b/chia-protocol/src/vdf.rs @@ -6,7 +6,7 @@ use crate::{Bytes, Bytes32}; streamable_struct!(VDFInfo { challenge: Bytes32, - number_of_iterations: u128, + number_of_iterations: u64, output: ClassgroupElement, }); diff --git a/chia-protocol/src/wallet_protocol.rs b/chia-protocol/src/wallet_protocol.rs index 85d853cc3..973924c60 100644 --- a/chia-protocol/src/wallet_protocol.rs +++ b/chia-protocol/src/wallet_protocol.rs @@ -45,7 +45,7 @@ message_struct! (TransactionAck { message_struct!(NewPeakWallet { header_hash: Bytes32, height: u32, - weight: u64, + weight: u128, fork_point_with_previous_peak: u32, }); diff --git a/chia-protocol/src/weight_proof.rs b/chia-protocol/src/weight_proof.rs index 88b55440f..e6eafb2f7 100644 --- a/chia-protocol/src/weight_proof.rs +++ b/chia-protocol/src/weight_proof.rs @@ -17,7 +17,7 @@ streamable_struct! (SubSlotData { icc_slot_end_info: Option, cc_ip_vdf_info: Option, icc_ip_vdf_info: Option, - total_iters: Option, + total_iters: Option, }); #[cfg(feature = "py-bindings")] diff --git a/chia-traits/src/from_json_dict.rs b/chia-traits/src/from_json_dict.rs index 2a14bf5a6..17e055873 100644 --- a/chia-traits/src/from_json_dict.rs +++ b/chia-traits/src/from_json_dict.rs @@ -39,7 +39,7 @@ from_json_primitive!(u32); from_json_primitive!(i32); from_json_primitive!(u64); from_json_primitive!(i64); -from_json_primitive!(u64); +from_json_primitive!(u128); from_json_primitive!(i128); from_json_primitive!(String); diff --git a/chia-traits/src/streamable.rs b/chia-traits/src/streamable.rs index 6d297d90b..c7338c447 100644 --- a/chia-traits/src/streamable.rs +++ b/chia-traits/src/streamable.rs @@ -313,7 +313,7 @@ fn test_parse_u64() { } #[test] -fn test_parse_u64() { +fn test_parse_u128() { from_bytes::(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 0); from_bytes::(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], 1); from_bytes::( diff --git a/src/gen/conditions.rs b/src/gen/conditions.rs index 36df61a57..67fc9433b 100644 --- a/src/gen/conditions.rs +++ b/src/gen/conditions.rs @@ -683,10 +683,10 @@ pub struct SpendBundleConditions { pub cost: u64, // the sum of all values of all spent coins - pub removal_amount: u64, + pub removal_amount: u128, // the sum of all amounts of CREATE_COIN conditions - pub addition_amount: u64, + pub addition_amount: u128, } #[derive(Default)] @@ -787,7 +787,7 @@ pub fn process_single_spend( state.spent_puzzles.insert(puzzle_hash); - ret.removal_amount += my_amount as u64; + ret.removal_amount += my_amount as u128; let mut spend = Spend::new(parent_id, my_amount, puzzle_hash, coin_id); @@ -898,7 +898,7 @@ pub fn parse_conditions( if !spend.create_coin.insert(new_coin) { return Err(ValidationErr(c, ErrorCode::DuplicateOutput)); } - ret.addition_amount += amount as u64; + ret.addition_amount += amount as u128; } Condition::AssertSecondsRelative(s) => { // keep the most strict condition. i.e. the highest limit @@ -1194,7 +1194,7 @@ pub fn validate_conditions( return Err(ValidationErr(spends, ErrorCode::MintingCoin)); } - if ret.removal_amount - ret.addition_amount < ret.reserve_fee as u64 { + if ret.removal_amount - ret.addition_amount < ret.reserve_fee as u128 { // the actual fee is lower than the reserved fee return Err(ValidationErr(spends, ErrorCode::ReserveFeeConditionFailed)); } diff --git a/src/gen/run_puzzle.rs b/src/gen/run_puzzle.rs index 46d196554..4ee5a79d6 100644 --- a/src/gen/run_puzzle.rs +++ b/src/gen/run_puzzle.rs @@ -33,7 +33,7 @@ pub fn run_puzzle( let Reduction(clvm_cost, conditions) = run_program(a, &dialect, puzzle, solution, max_cost)?; let mut ret = SpendBundleConditions { - removal_amount: amount as u64, + removal_amount: amount as u128, ..Default::default() }; let mut state = ParseState::default(); diff --git a/wasm-patch/src/lib.rs b/wasm-patch/src/lib.rs index 7c1f339d3..92b88a1b4 100644 --- a/wasm-patch/src/lib.rs +++ b/wasm-patch/src/lib.rs @@ -37,3 +37,12 @@ pub fn with_wasm(_args: TokenStream, input: TokenStream) -> TokenStream { let input_maybe_modified = quote::quote!(#ast); _patch_issue_3707(&input_maybe_modified.into()) } + +#[proc_macro_attribute] +pub fn conv_u128_to_u64_for_wasm(_args: TokenStream, input: TokenStream) -> TokenStream { + let mut ast: syn::ImplItemFn = syn::parse(input.into()).unwrap(); + let mut converter = TypeConverter; + converter.visit_impl_item_fn_mut(&mut ast); + + quote::quote!(#ast).into() +} diff --git a/wheel/src/run_generator.rs b/wheel/src/run_generator.rs index 3b578a535..57e93afd9 100644 --- a/wheel/src/run_generator.rs +++ b/wheel/src/run_generator.rs @@ -60,9 +60,9 @@ pub struct PySpendBundleConditions { pub agg_sig_unsafe: Vec<(Bytes48, Bytes)>, pub cost: u64, // the sum of all values of all spent coins - pub removal_amount: u64, + pub removal_amount: u128, // the sum of all amounts of CREATE_COIN conditions - pub addition_amount: u64, + pub addition_amount: u128, } fn convert_agg_sigs(a: &Allocator, agg_sigs: &[(NodePtr, NodePtr)]) -> Vec<(Bytes48, Bytes)> { From 3fe0a84cb16fba1018f9d431ba686b272613c3c2 Mon Sep 17 00:00:00 2001 From: Izumi Hoshino Date: Wed, 31 Jan 2024 00:38:30 +0900 Subject: [PATCH 6/6] Updated wasm_bindgen to 0.2.90 --- Cargo.lock | 21 ++++++++++----------- chia-bls/Cargo.toml | 2 +- chia-protocol/Cargo.toml | 2 +- chia-protocol/src/coin.rs | 4 ++-- wasm/Cargo.toml | 3 +-- 5 files changed, 15 insertions(+), 17 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e024ba123..68f645aef 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -489,7 +489,6 @@ name = "chia_wasm" version = "0.2.7" dependencies = [ "chia", - "chia-protocol", "js-sys", "wasm-bindgen", "wasm-bindgen-test", @@ -2573,9 +2572,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.88" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7daec296f25a1bae309c0cd5c29c4b260e510e6d813c286b19eaadf409d40fce" +checksum = "b1223296a201415c7fad14792dbefaace9bd52b62d33453ade1c5b5f07555406" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -2583,9 +2582,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.88" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e397f4664c0e4e428e8313a469aaa58310d302159845980fd23b0f22a847f217" +checksum = "fcdc935b63408d58a32f8cc9738a0bffd8f05cc7c002086c6ef20b7312ad9dcd" dependencies = [ "bumpalo", "log", @@ -2610,9 +2609,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.88" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5961017b3b08ad5f3fe39f1e79877f8ee7c23c5e5fd5eb80de95abc41f1f16b2" +checksum = "3e4c238561b2d428924c49815533a8b9121c664599558a5d9ec51f8a1740a999" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2620,9 +2619,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.88" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5353b8dab669f5e10f5bd76df26a9360c748f054f862ff5f3f8aae0c7fb3907" +checksum = "bae1abb6806dc1ad9e560ed242107c0f6c84335f1749dd4e8ddb012ebd5e25a7" dependencies = [ "proc-macro2", "quote", @@ -2633,9 +2632,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.88" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d046c5d029ba91a1ed14da14dca44b68bf2f124cfbaf741c54151fdb3e0750b" +checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b" [[package]] name = "wasm-bindgen-test" diff --git a/chia-bls/Cargo.toml b/chia-bls/Cargo.toml index 4674af341..d48a82572 100644 --- a/chia-bls/Cargo.toml +++ b/chia-bls/Cargo.toml @@ -27,7 +27,7 @@ pyo3 = { version = "0.19.0", features = ["multiple-pymethods"], optional = true arbitrary = { version = "1.3.0" } [target.'cfg(target_arch = "wasm32")'.dependencies] -wasm-bindgen = "0.2.88" +wasm-bindgen = "0.2.90" wasm-patch = { version = "0.1.0", path = "../wasm-patch" } [dev-dependencies] diff --git a/chia-protocol/Cargo.toml b/chia-protocol/Cargo.toml index fb72e29b2..26bef7e3d 100644 --- a/chia-protocol/Cargo.toml +++ b/chia-protocol/Cargo.toml @@ -24,7 +24,7 @@ chia-bls = { version = "0.2.13", path = "../chia-bls" } arbitrary = { version = "1.3.0", features = ["derive"] } [target.'cfg(target_arch = "wasm32")'.dependencies] -wasm-bindgen = "0.2.88" +wasm-bindgen = "0.2.90" paste = "1.0.14" wasm-patch = { version = "0.1.0", path = "../wasm-patch" } diff --git a/chia-protocol/src/coin.rs b/chia-protocol/src/coin.rs index 1afc62126..8f64efc84 100644 --- a/chia-protocol/src/coin.rs +++ b/chia-protocol/src/coin.rs @@ -1,3 +1,4 @@ +use crate::streamable_struct; use crate::bytes::Bytes32; use chia_streamable_macro::Streamable; use clvm_traits::{clvm_list, destructure_list, match_list, FromClvm, ToClvm}; @@ -9,8 +10,7 @@ use std::convert::TryInto; #[cfg(feature = "py-bindings")] use pyo3::prelude::*; -//* -crate::streamable_struct!(Coin { +streamable_struct!(Coin { parent_coin_info: Bytes32, puzzle_hash: Bytes32, amount: u64, diff --git a/wasm/Cargo.toml b/wasm/Cargo.toml index e420b3c5d..7185c1e9e 100644 --- a/wasm/Cargo.toml +++ b/wasm/Cargo.toml @@ -16,7 +16,6 @@ path = "src/lib.rs" [dependencies] chia = { path = ".." } -chia-protocol = { path = "../chia-protocol"} -wasm-bindgen = "=0.2.88" +wasm-bindgen = "=0.2.90" wasm-bindgen-test = "=0.3.37" js-sys = "=0.3.64"