From 0dded2d11fc823214b72e9826f2ef65b822188ae Mon Sep 17 00:00:00 2001 From: andrea Date: Wed, 20 Nov 2024 15:04:26 -0800 Subject: [PATCH] WASM: use a macro to simplify the definition of binding types This reduces the amount of repeated code. Also, it adds some conversions that were previously not implemented. --- ironfish-rust-wasm/src/assets.rs | 37 +---- ironfish-rust-wasm/src/keys/public_address.rs | 21 +-- ironfish-rust-wasm/src/lib.rs | 60 ++++++++ ironfish-rust-wasm/src/merkle_note.rs | 38 +---- ironfish-rust-wasm/src/primitives.rs | 138 ++++-------------- ironfish-rust-wasm/src/transaction/burns.rs | 21 +-- ironfish-rust-wasm/src/transaction/mints.rs | 20 +-- ironfish-rust-wasm/src/transaction/mod.rs | 21 +-- ironfish-rust-wasm/src/transaction/outputs.rs | 20 +-- ironfish-rust-wasm/src/transaction/spends.rs | 20 +-- 10 files changed, 131 insertions(+), 265 deletions(-) diff --git a/ironfish-rust-wasm/src/assets.rs b/ironfish-rust-wasm/src/assets.rs index b0606caeeb..a863c44c9a 100644 --- a/ironfish-rust-wasm/src/assets.rs +++ b/ironfish-rust-wasm/src/assets.rs @@ -6,13 +6,15 @@ use crate::{ errors::IronfishError, keys::PublicAddress, primitives::{ExtendedPoint, SubgroupPoint}, + wasm_bindgen_wrapper, }; use ironfish::errors::IronfishErrorKind; use wasm_bindgen::prelude::*; -#[wasm_bindgen] -#[derive(Clone, PartialEq, Eq, Debug)] -pub struct Asset(ironfish::assets::asset::Asset); +wasm_bindgen_wrapper! { + #[derive(Clone, PartialEq, Eq, Debug)] + pub struct Asset(ironfish::assets::asset::Asset); +} #[wasm_bindgen] impl Asset { @@ -99,22 +101,11 @@ impl Asset { } } -impl From for Asset { - fn from(d: ironfish::assets::asset::Asset) -> Self { - Self(d) - } +wasm_bindgen_wrapper! { + #[derive(Clone, PartialEq, Eq, Debug)] + pub struct AssetIdentifier(ironfish::assets::asset_identifier::AssetIdentifier); } -impl AsRef for Asset { - fn as_ref(&self) -> &ironfish::assets::asset::Asset { - &self.0 - } -} - -#[wasm_bindgen] -#[derive(Clone, PartialEq, Eq, Debug)] -pub struct AssetIdentifier(ironfish::assets::asset_identifier::AssetIdentifier); - #[wasm_bindgen] impl AssetIdentifier { #[wasm_bindgen(constructor)] @@ -140,18 +131,6 @@ impl AssetIdentifier { } } -impl From for AssetIdentifier { - fn from(d: ironfish::assets::asset_identifier::AssetIdentifier) -> Self { - Self(d) - } -} - -impl AsRef for AssetIdentifier { - fn as_ref(&self) -> &ironfish::assets::asset_identifier::AssetIdentifier { - &self.0 - } -} - #[cfg(test)] mod tests { mod asset { diff --git a/ironfish-rust-wasm/src/keys/public_address.rs b/ironfish-rust-wasm/src/keys/public_address.rs index 3f2e91dba0..8ceda76464 100644 --- a/ironfish-rust-wasm/src/keys/public_address.rs +++ b/ironfish-rust-wasm/src/keys/public_address.rs @@ -2,12 +2,13 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -use crate::errors::IronfishError; +use crate::{errors::IronfishError, wasm_bindgen_wrapper}; use wasm_bindgen::prelude::*; -#[wasm_bindgen] -#[derive(Clone, PartialEq, Eq, Debug)] -pub struct PublicAddress(ironfish::PublicAddress); +wasm_bindgen_wrapper! { + #[derive(Clone, PartialEq, Eq, Debug)] + pub struct PublicAddress(ironfish::PublicAddress); +} #[wasm_bindgen] impl PublicAddress { @@ -32,18 +33,6 @@ impl PublicAddress { } } -impl From for PublicAddress { - fn from(d: ironfish::PublicAddress) -> Self { - Self(d) - } -} - -impl AsRef for PublicAddress { - fn as_ref(&self) -> &ironfish::PublicAddress { - &self.0 - } -} - #[cfg(test)] mod tests { use crate::keys::public_address::PublicAddress; diff --git a/ironfish-rust-wasm/src/lib.rs b/ironfish-rust-wasm/src/lib.rs index 0e4865b20c..ae1e56da2c 100644 --- a/ironfish-rust-wasm/src/lib.rs +++ b/ironfish-rust-wasm/src/lib.rs @@ -22,6 +22,66 @@ pub mod merkle_note; pub mod primitives; pub mod transaction; +/// Creates a [`wasm_bindgen`] wrapper for an existing type. +/// +/// This macro can be invoked as follows: +/// +/// ``` +/// wasm_bindgen_wrapper! { +/// #[derive(Clone, Debug)] +/// pub struct FooBinding(Foo); +/// } +/// ``` +/// +/// and expands to the following: +/// +/// ``` +/// #[wasm_bindgen] +/// #[derive(Clone, Debug)] +/// pub struct FooBinding(Foo); +/// +/// impl From for FooBinding { ... } +/// impl From for Foo { ... } +/// impl AsRef for FooBinding { ... } +/// impl Borrow for FooBinding { ... } +/// ``` +macro_rules! wasm_bindgen_wrapper { + ($( + $( #[ $meta:meta ] )* + $vis:vis struct $name:ident ( $inner:ty ) ; + )*) => {$( + $(#[$meta])* + #[::wasm_bindgen::prelude::wasm_bindgen] + $vis struct $name($inner); + + impl ::std::convert::From<$inner> for $name { + fn from(x: $inner) -> Self { + Self(x) + } + } + + impl ::std::convert::From<$name> for $inner { + fn from(x: $name) -> Self { + x.0 + } + } + + impl ::std::convert::AsRef<$inner> for $name { + fn as_ref(&self) -> &$inner { + &self.0 + } + } + + impl ::std::borrow::Borrow<$inner> for $name { + fn borrow(&self) -> &$inner { + &self.0 + } + } + )*} +} + +use wasm_bindgen_wrapper; + #[cfg(test)] mod tests { wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser); diff --git a/ironfish-rust-wasm/src/merkle_note.rs b/ironfish-rust-wasm/src/merkle_note.rs index a02d1ec444..b19e5e30e5 100644 --- a/ironfish-rust-wasm/src/merkle_note.rs +++ b/ironfish-rust-wasm/src/merkle_note.rs @@ -2,12 +2,13 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -use crate::{errors::IronfishError, primitives::Scalar}; +use crate::{errors::IronfishError, primitives::Scalar, wasm_bindgen_wrapper}; use wasm_bindgen::prelude::*; -#[wasm_bindgen] -#[derive(Clone, PartialEq, Eq, Debug)] -pub struct MerkleNote(ironfish::MerkleNote); +wasm_bindgen_wrapper! { + #[derive(Clone, PartialEq, Eq, Debug)] + pub struct MerkleNote(ironfish::MerkleNote); +} #[wasm_bindgen] impl MerkleNote { @@ -31,22 +32,11 @@ impl MerkleNote { } } -impl From for MerkleNote { - fn from(d: ironfish::MerkleNote) -> Self { - Self(d) - } +wasm_bindgen_wrapper! { + #[derive(Clone, PartialEq, Eq, Debug)] + pub struct MerkleNoteHash(ironfish::MerkleNoteHash); } -impl AsRef for MerkleNote { - fn as_ref(&self) -> &ironfish::MerkleNote { - &self.0 - } -} - -#[wasm_bindgen] -#[derive(Clone, PartialEq, Eq, Debug)] -pub struct MerkleNoteHash(ironfish::MerkleNoteHash); - #[wasm_bindgen] impl MerkleNoteHash { #[wasm_bindgen(constructor)] @@ -80,18 +70,6 @@ impl MerkleNoteHash { } } -impl From for MerkleNoteHash { - fn from(d: ironfish::MerkleNoteHash) -> Self { - Self(d) - } -} - -impl AsRef for MerkleNoteHash { - fn as_ref(&self) -> &ironfish::MerkleNoteHash { - &self.0 - } -} - #[cfg(test)] mod tests { use crate::merkle_note::MerkleNoteHash; diff --git a/ironfish-rust-wasm/src/primitives.rs b/ironfish-rust-wasm/src/primitives.rs index 99517956ac..8eb38fc640 100644 --- a/ironfish-rust-wasm/src/primitives.rs +++ b/ironfish-rust-wasm/src/primitives.rs @@ -2,16 +2,17 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -use crate::errors::IronfishError; +use crate::{errors::IronfishError, wasm_bindgen_wrapper}; use group::GroupEncoding; use ironfish::errors::IronfishErrorKind; use ironfish_zkp::redjubjub; use rand::thread_rng; use wasm_bindgen::prelude::*; -#[wasm_bindgen] -#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug)] -pub struct Scalar(blstrs::Scalar); +wasm_bindgen_wrapper! { + #[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug)] + pub struct Scalar(blstrs::Scalar); +} #[wasm_bindgen] impl Scalar { @@ -26,22 +27,11 @@ impl Scalar { } } -impl From for Scalar { - fn from(s: blstrs::Scalar) -> Self { - Self(s) - } -} - -impl AsRef for Scalar { - fn as_ref(&self) -> &blstrs::Scalar { - &self.0 - } +wasm_bindgen_wrapper! { + #[derive(Default, Copy, Clone, PartialEq, Eq, Debug)] + pub struct Fr(ironfish_jubjub::Fr); } -#[wasm_bindgen] -#[derive(Default, Copy, Clone, PartialEq, Eq, Debug)] -pub struct Fr(ironfish_jubjub::Fr); - #[wasm_bindgen] impl Fr { #[wasm_bindgen(js_name = toBytes)] @@ -50,22 +40,11 @@ impl Fr { } } -impl From for Fr { - fn from(s: ironfish_jubjub::Fr) -> Self { - Self(s) - } -} - -impl AsRef for Fr { - fn as_ref(&self) -> &ironfish_jubjub::Fr { - &self.0 - } +wasm_bindgen_wrapper! { + #[derive(Default, Copy, Clone, PartialEq, Eq, Debug)] + pub struct ExtendedPoint(ironfish_jubjub::ExtendedPoint); } -#[wasm_bindgen] -#[derive(Default, Copy, Clone, PartialEq, Eq, Debug)] -pub struct ExtendedPoint(ironfish_jubjub::ExtendedPoint); - #[wasm_bindgen] impl ExtendedPoint { #[wasm_bindgen(js_name = toBytes)] @@ -74,22 +53,11 @@ impl ExtendedPoint { } } -impl From for ExtendedPoint { - fn from(s: ironfish_jubjub::ExtendedPoint) -> Self { - Self(s) - } -} - -impl AsRef for ExtendedPoint { - fn as_ref(&self) -> &ironfish_jubjub::ExtendedPoint { - &self.0 - } +wasm_bindgen_wrapper! { + #[derive(Default, Copy, Clone, PartialEq, Eq, Debug)] + pub struct SubgroupPoint(ironfish_jubjub::SubgroupPoint); } -#[wasm_bindgen] -#[derive(Default, Copy, Clone, PartialEq, Eq, Debug)] -pub struct SubgroupPoint(ironfish_jubjub::SubgroupPoint); - #[wasm_bindgen] impl SubgroupPoint { #[wasm_bindgen(js_name = toBytes)] @@ -98,22 +66,11 @@ impl SubgroupPoint { } } -impl From for SubgroupPoint { - fn from(s: ironfish_jubjub::SubgroupPoint) -> Self { - Self(s) - } -} - -impl AsRef for SubgroupPoint { - fn as_ref(&self) -> &ironfish_jubjub::SubgroupPoint { - &self.0 - } +wasm_bindgen_wrapper! { + #[derive(Copy, Clone, PartialEq, Eq, Debug)] + pub struct Nullifier(ironfish_zkp::Nullifier); } -#[wasm_bindgen] -#[derive(Copy, Clone, PartialEq, Eq, Debug)] -pub struct Nullifier(ironfish_zkp::Nullifier); - #[wasm_bindgen] impl Nullifier { #[wasm_bindgen(js_name = toBytes)] @@ -122,21 +79,10 @@ impl Nullifier { } } -impl From for Nullifier { - fn from(s: ironfish_zkp::Nullifier) -> Self { - Self(s) - } +wasm_bindgen_wrapper! { + pub struct PrivateKey(redjubjub::PrivateKey); } -impl AsRef for Nullifier { - fn as_ref(&self) -> &ironfish_zkp::Nullifier { - &self.0 - } -} - -#[wasm_bindgen] -pub struct PrivateKey(redjubjub::PrivateKey); - #[wasm_bindgen] impl PrivateKey { #[wasm_bindgen(constructor)] @@ -168,22 +114,11 @@ impl PrivateKey { } } -impl From for PrivateKey { - fn from(p: redjubjub::PrivateKey) -> Self { - Self(p) - } -} - -impl AsRef for PrivateKey { - fn as_ref(&self) -> &redjubjub::PrivateKey { - &self.0 - } +wasm_bindgen_wrapper! { + #[derive(Clone, Debug)] + pub struct PublicKey(redjubjub::PublicKey); } -#[wasm_bindgen] -#[derive(Clone, Debug)] -pub struct PublicKey(redjubjub::PublicKey); - #[wasm_bindgen] impl PublicKey { #[wasm_bindgen(constructor)] @@ -218,22 +153,11 @@ impl PublicKey { } } -impl From for PublicKey { - fn from(p: redjubjub::PublicKey) -> Self { - Self(p) - } -} - -impl AsRef for PublicKey { - fn as_ref(&self) -> &redjubjub::PublicKey { - &self.0 - } +wasm_bindgen_wrapper! { + #[derive(Clone, Debug)] + pub struct Signature(redjubjub::Signature); } -#[wasm_bindgen] -#[derive(Clone, Debug)] -pub struct Signature(redjubjub::Signature); - #[wasm_bindgen] impl Signature { #[wasm_bindgen(constructor)] @@ -249,15 +173,3 @@ impl Signature { buf } } - -impl From for Signature { - fn from(s: redjubjub::Signature) -> Self { - Self(s) - } -} - -impl AsRef for Signature { - fn as_ref(&self) -> &redjubjub::Signature { - &self.0 - } -} diff --git a/ironfish-rust-wasm/src/transaction/burns.rs b/ironfish-rust-wasm/src/transaction/burns.rs index 7224e4b9db..f5b3d603fc 100644 --- a/ironfish-rust-wasm/src/transaction/burns.rs +++ b/ironfish-rust-wasm/src/transaction/burns.rs @@ -2,12 +2,13 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -use crate::{assets::AssetIdentifier, errors::IronfishError}; +use crate::{assets::AssetIdentifier, errors::IronfishError, wasm_bindgen_wrapper}; use wasm_bindgen::prelude::*; -#[wasm_bindgen] -#[derive(Clone, PartialEq, Eq, Debug)] -pub struct BurnDescription(ironfish::transaction::burns::BurnDescription); +wasm_bindgen_wrapper! { + #[derive(Clone, PartialEq, Eq, Debug)] + pub struct BurnDescription(ironfish::transaction::burns::BurnDescription); +} #[wasm_bindgen] impl BurnDescription { @@ -37,15 +38,3 @@ impl BurnDescription { self.0.value } } - -impl From for BurnDescription { - fn from(d: ironfish::transaction::burns::BurnDescription) -> Self { - Self(d) - } -} - -impl AsRef for BurnDescription { - fn as_ref(&self) -> &ironfish::transaction::burns::BurnDescription { - &self.0 - } -} diff --git a/ironfish-rust-wasm/src/transaction/mints.rs b/ironfish-rust-wasm/src/transaction/mints.rs index d9975c3555..ba03caca8d 100644 --- a/ironfish-rust-wasm/src/transaction/mints.rs +++ b/ironfish-rust-wasm/src/transaction/mints.rs @@ -7,13 +7,15 @@ use crate::{ errors::IronfishError, keys::PublicAddress, primitives::{PublicKey, Scalar}, + wasm_bindgen_wrapper, }; use ironfish::{errors::IronfishErrorKind, transaction::TransactionVersion}; use wasm_bindgen::prelude::*; -#[wasm_bindgen] -#[derive(Clone, Debug)] -pub struct MintDescription(ironfish::transaction::mints::MintDescription); +wasm_bindgen_wrapper! { + #[derive(Clone, Debug)] + pub struct MintDescription(ironfish::transaction::mints::MintDescription); +} #[wasm_bindgen] impl MintDescription { @@ -77,15 +79,3 @@ impl MintDescription { .collect() } } - -impl From for MintDescription { - fn from(d: ironfish::transaction::mints::MintDescription) -> Self { - Self(d) - } -} - -impl AsRef for MintDescription { - fn as_ref(&self) -> &ironfish::transaction::mints::MintDescription { - &self.0 - } -} diff --git a/ironfish-rust-wasm/src/transaction/mod.rs b/ironfish-rust-wasm/src/transaction/mod.rs index 18d2d0b65a..4e534bc18e 100644 --- a/ironfish-rust-wasm/src/transaction/mod.rs +++ b/ironfish-rust-wasm/src/transaction/mod.rs @@ -7,7 +7,7 @@ mod mints; mod outputs; mod spends; -use crate::{errors::IronfishError, primitives::PublicKey}; +use crate::{errors::IronfishError, primitives::PublicKey, wasm_bindgen_wrapper}; use wasm_bindgen::prelude::*; pub use burns::BurnDescription; @@ -15,9 +15,10 @@ pub use mints::MintDescription; pub use outputs::OutputDescription; pub use spends::SpendDescription; -#[wasm_bindgen] -#[derive(Clone, Debug)] -pub struct Transaction(ironfish::Transaction); +wasm_bindgen_wrapper! { + #[derive(Clone, Debug)] + pub struct Transaction(ironfish::Transaction); +} #[wasm_bindgen] impl Transaction { @@ -99,18 +100,6 @@ impl Transaction { } } -impl From for Transaction { - fn from(t: ironfish::Transaction) -> Self { - Self(t) - } -} - -impl AsRef for Transaction { - fn as_ref(&self) -> &ironfish::Transaction { - &self.0 - } -} - #[cfg(test)] mod tests { use super::Transaction; diff --git a/ironfish-rust-wasm/src/transaction/outputs.rs b/ironfish-rust-wasm/src/transaction/outputs.rs index 5f63b72ad1..64ed7b4c17 100644 --- a/ironfish-rust-wasm/src/transaction/outputs.rs +++ b/ironfish-rust-wasm/src/transaction/outputs.rs @@ -6,12 +6,14 @@ use crate::{ errors::IronfishError, merkle_note::MerkleNote, primitives::{PublicKey, Scalar}, + wasm_bindgen_wrapper, }; use wasm_bindgen::prelude::*; -#[wasm_bindgen] -#[derive(Clone, PartialEq, Debug)] -pub struct OutputDescription(ironfish::OutputDescription); +wasm_bindgen_wrapper! { + #[derive(Clone, PartialEq, Debug)] + pub struct OutputDescription(ironfish::OutputDescription); +} #[wasm_bindgen] impl OutputDescription { @@ -48,15 +50,3 @@ impl OutputDescription { self.0.merkle_note().into() } } - -impl From for OutputDescription { - fn from(d: ironfish::OutputDescription) -> Self { - Self(d) - } -} - -impl AsRef for OutputDescription { - fn as_ref(&self) -> &ironfish::OutputDescription { - &self.0 - } -} diff --git a/ironfish-rust-wasm/src/transaction/spends.rs b/ironfish-rust-wasm/src/transaction/spends.rs index 6ce969b2fc..92eadaa2c8 100644 --- a/ironfish-rust-wasm/src/transaction/spends.rs +++ b/ironfish-rust-wasm/src/transaction/spends.rs @@ -5,13 +5,15 @@ use crate::{ errors::IronfishError, primitives::{Nullifier, PublicKey, Scalar}, + wasm_bindgen_wrapper, }; use ironfish::errors::IronfishErrorKind; use wasm_bindgen::prelude::*; -#[wasm_bindgen] -#[derive(Clone, Debug)] -pub struct SpendDescription(ironfish::SpendDescription); +wasm_bindgen_wrapper! { + #[derive(Clone, Debug)] + pub struct SpendDescription(ironfish::SpendDescription); +} #[wasm_bindgen] impl SpendDescription { @@ -72,15 +74,3 @@ impl SpendDescription { .collect() } } - -impl From for SpendDescription { - fn from(d: ironfish::SpendDescription) -> Self { - Self(d) - } -} - -impl AsRef for SpendDescription { - fn as_ref(&self) -> &ironfish::SpendDescription { - &self.0 - } -}