From 82830062a2440dfcef80c25f1af3b17cf78332b7 Mon Sep 17 00:00:00 2001 From: Filip Date: Wed, 10 Mar 2021 21:54:45 +0100 Subject: [PATCH 1/8] Added orml pallets --- Cargo.lock | 99 ++++++++++++++++++++++++++++++++++----- pallets/mixer/Cargo.toml | 3 ++ pallets/mixer/src/lib.rs | 2 + pallets/mixer/src/mock.rs | 40 ++++++++++++++++ 4 files changed, 133 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9e7935d4..3340a89f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1640,7 +1640,7 @@ dependencies = [ "bitflags", "frame-metadata", "frame-support-procedural", - "impl-trait-for-tuples", + "impl-trait-for-tuples 0.2.1", "log", "once_cell", "parity-scale-codec 2.0.1", @@ -1698,7 +1698,7 @@ version = "3.0.0" source = "git+https://github.com/paritytech/substrate.git?rev=49a4103#49a4103f4bfef55be20a5c6d26e18ff3003c3353" dependencies = [ "frame-support", - "impl-trait-for-tuples", + "impl-trait-for-tuples 0.2.1", "parity-scale-codec 2.0.1", "serde", "sp-core", @@ -2416,6 +2416,17 @@ dependencies = [ "serde", ] +[[package]] +name = "impl-trait-for-tuples" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef5550a42e3740a0e71f909d4c861056a284060af885ae7aa6242820f920d9d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "impl-trait-for-tuples" version = "0.2.1" @@ -3817,6 +3828,69 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" +[[package]] +name = "orml-currencies" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "204fa52ab72cf353879bf57a6cccc64d1fadf3d44246d98007b218cc22fc4d06" +dependencies = [ + "frame-support", + "frame-system", + "funty", + "orml-traits", + "orml-utilities", + "parity-scale-codec 2.0.1", + "sp-io", + "sp-runtime", + "sp-std 3.0.0", +] + +[[package]] +name = "orml-tokens" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0321e56f921689c6c78bf2b68e3deb03172065ca8f306d4d8432d09c3569bb9d" +dependencies = [ + "frame-support", + "frame-system", + "funty", + "orml-traits", + "parity-scale-codec 2.0.1", + "sp-runtime", + "sp-std 3.0.0", +] + +[[package]] +name = "orml-traits" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18dd4788a7b96709d23081b1a33a5b8477cf25833f20b27b19908d5babdfe7ab" +dependencies = [ + "frame-support", + "funty", + "impl-trait-for-tuples 0.1.3", + "num-traits", + "orml-utilities", + "parity-scale-codec 2.0.1", + "sp-io", + "sp-runtime", + "sp-std 3.0.0", +] + +[[package]] +name = "orml-utilities" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f84d1a0ce4c65a8695cf8c41895c6161d2345214a4a413e674478f6a37968db" +dependencies = [ + "frame-support", + "funty", + "parity-scale-codec 2.0.1", + "sp-io", + "sp-runtime", + "sp-std 3.0.0", +] + [[package]] name = "owning_ref" version = "0.4.1" @@ -3851,7 +3925,7 @@ source = "git+https://github.com/paritytech/substrate.git?rev=49a4103#49a4103f4b dependencies = [ "frame-support", "frame-system", - "impl-trait-for-tuples", + "impl-trait-for-tuples 0.2.1", "parity-scale-codec 2.0.1", "sp-authorship", "sp-inherents", @@ -3986,6 +4060,9 @@ dependencies = [ "frame-support", "frame-system", "merlin", + "orml-currencies", + "orml-tokens", + "orml-traits", "pallet-balances", "pallet-merkle", "parity-scale-codec 2.0.1", @@ -4016,7 +4093,7 @@ source = "git+https://github.com/paritytech/substrate.git?rev=49a4103#49a4103f4b dependencies = [ "frame-support", "frame-system", - "impl-trait-for-tuples", + "impl-trait-for-tuples 0.2.1", "pallet-timestamp", "parity-scale-codec 2.0.1", "serde", @@ -4051,7 +4128,7 @@ dependencies = [ "frame-benchmarking 3.0.0", "frame-support", "frame-system", - "impl-trait-for-tuples", + "impl-trait-for-tuples 0.2.1", "parity-scale-codec 2.0.1", "serde", "sp-inherents", @@ -4223,7 +4300,7 @@ checksum = "664a8c6b8e62d8f9f2f937e391982eb433ab285b4cd9545b342441e04a906e42" dependencies = [ "cfg-if 1.0.0", "hashbrown", - "impl-trait-for-tuples", + "impl-trait-for-tuples 0.2.1", "parity-util-mem-derive", "parking_lot 0.11.1", "primitive-types", @@ -5287,7 +5364,7 @@ name = "sc-chain-spec" version = "3.0.0" source = "git+https://github.com/paritytech/substrate.git?rev=49a4103#49a4103f4bfef55be20a5c6d26e18ff3003c3353" dependencies = [ - "impl-trait-for-tuples", + "impl-trait-for-tuples 0.2.1", "parity-scale-codec 2.0.1", "sc-chain-spec-derive", "sc-consensus-babe", @@ -6828,7 +6905,7 @@ source = "git+https://github.com/paritytech/substrate.git?rev=49a4103#49a4103f4b dependencies = [ "either", "hash256-std-hasher", - "impl-trait-for-tuples", + "impl-trait-for-tuples 0.2.1", "log", "parity-scale-codec 2.0.1", "parity-util-mem", @@ -6847,7 +6924,7 @@ name = "sp-runtime-interface" version = "3.0.0" source = "git+https://github.com/paritytech/substrate.git?rev=49a4103#49a4103f4bfef55be20a5c6d26e18ff3003c3353" dependencies = [ - "impl-trait-for-tuples", + "impl-trait-for-tuples 0.2.1", "parity-scale-codec 2.0.1", "primitive-types", "sp-externalities", @@ -6980,7 +7057,7 @@ name = "sp-timestamp" version = "3.0.0" source = "git+https://github.com/paritytech/substrate.git?rev=49a4103#49a4103f4bfef55be20a5c6d26e18ff3003c3353" dependencies = [ - "impl-trait-for-tuples", + "impl-trait-for-tuples 0.2.1", "parity-scale-codec 2.0.1", "sp-api", "sp-inherents", @@ -7061,7 +7138,7 @@ name = "sp-wasm-interface" version = "3.0.0" source = "git+https://github.com/paritytech/substrate.git?rev=49a4103#49a4103f4bfef55be20a5c6d26e18ff3003c3353" dependencies = [ - "impl-trait-for-tuples", + "impl-trait-for-tuples 0.2.1", "parity-scale-codec 2.0.1", "sp-std 3.0.0", "wasmi", diff --git a/pallets/mixer/Cargo.toml b/pallets/mixer/Cargo.toml index 6d53b722..7243e479 100644 --- a/pallets/mixer/Cargo.toml +++ b/pallets/mixer/Cargo.toml @@ -20,6 +20,9 @@ serde = { version = "1.0.101", optional = true, features = ["derive"] } bulletproofs = { version = "2.0.0", branch = "main", git = "https://github.com/edgeware-builders/bulletproofs", default-features = false, features = ["yoloproofs"] } merlin = { version = "2.0.0", default-features = false } frame-benchmarking = { default-features = false, version = "3.0.0", optional = true } +orml-traits = { version = "0.4.0", default-features = false } +orml-currencies = { version = "0.4.0", default-features = false } +orml-tokens = { version = "0.4.0", default-features = false } [dependencies.curve25519-gadgets] rev = "6157520" diff --git a/pallets/mixer/src/lib.rs b/pallets/mixer/src/lib.rs index 4964305d..47cdd4d0 100644 --- a/pallets/mixer/src/lib.rs +++ b/pallets/mixer/src/lib.rs @@ -68,6 +68,7 @@ use merkle::{ }, Group as GroupTrait, Module as MerkleModule, }; +use orml_traits::MultiCurrency; use sp_runtime::{ traits::{AccountIdConversion, Zero}, ModuleId, @@ -93,6 +94,7 @@ pub mod pallet { type Event: IsType<::Event> + From>; /// Currency type for taking deposits type Currency: Currency; + type MultiCurrency: MultiCurrency; /// The overarching group trait type Group: GroupTrait; /// The max depth of the mixers diff --git a/pallets/mixer/src/mock.rs b/pallets/mixer/src/mock.rs index 6745f64d..a1360cd7 100644 --- a/pallets/mixer/src/mock.rs +++ b/pallets/mixer/src/mock.rs @@ -3,6 +3,8 @@ use crate as pallet_mixer; use frame_support::{construct_runtime, parameter_types, weights::Weight}; use frame_system::mocking::{MockBlock, MockUncheckedExtrinsic}; use merkle::weights::Weights as MerkleWeights; +use orml_currencies::BasicCurrencyAdapter; +use orml_traits::parameter_type_with_key; use pallet_mixer::weights::Weights; use sp_core::H256; use sp_runtime::{ @@ -10,7 +12,11 @@ use sp_runtime::{ traits::{BlakeTwo256, IdentityLookup}, ModuleId, Perbill, }; + pub(crate) type Balance = u64; +pub type Amount = i128; +pub type CurrencyId = u64; +pub type BlockNumber = u64; // Configure a mock runtime to test the pallet. type UncheckedExtrinsic = MockUncheckedExtrinsic; @@ -26,6 +32,8 @@ construct_runtime!( Balances: balances::{Module, Call, Storage, Config, Event}, MerkleGroups: merkle::{Module, Call, Storage, Event}, Mixer: pallet_mixer::{Module, Call, Storage, Event}, + Currencies: orml_currencies::{Module, Storage, Event}, + Tokens: orml_tokens::{Module, Storage, Event}, } ); @@ -81,6 +89,37 @@ impl balances::Config for Test { type WeightInfo = (); } +parameter_type_with_key! { + pub ExistentialDepositMap: |k: CurrencyId| -> Balance { + match k { + 1 => 1, + _ => 2, + } + }; +} + +parameter_types! { + pub const NativeCurrencyId: CurrencyId = 0; +} + +impl orml_tokens::Config for Test { + type Amount = Amount; + type Balance = Balance; + type CurrencyId = CurrencyId; + type Event = Event; + type ExistentialDeposits = ExistentialDepositMap; + type OnDust = (); + type WeightInfo = (); +} + +impl orml_currencies::Config for Test { + type Event = Event; + type GetNativeCurrencyId = NativeCurrencyId; + type MultiCurrency = Tokens; + type NativeCurrency = BasicCurrencyAdapter; + type WeightInfo = (); +} + impl merkle::Config for Test { type CacheBlockLength = CacheBlockLength; type Event = Event; @@ -104,6 +143,7 @@ impl Config for Test { type MaxMixerTreeDepth = MaxTreeDepth; type MixerSizes = MixerSizes; type ModuleId = MixerModuleId; + type MultiCurrency = Currencies; type WeightInfo = Weights; } From 18aef501a0ff5aec8823a31226f434c7d81ed6da Mon Sep 17 00:00:00 2001 From: Filip Date: Thu, 11 Mar 2021 10:52:40 +0100 Subject: [PATCH 2/8] Update config and types --- Cargo.lock | 8 +++--- pallets/mixer/src/lib.rs | 55 +++++++++++++++++++++------------------ pallets/mixer/src/mock.rs | 4 +-- 3 files changed, 34 insertions(+), 33 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c74923f6..92c939b8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1160,14 +1160,12 @@ dependencies = [ [[package]] name = "curve25519-gadgets" version = "2.0.0" -source = "git+https://github.com/webb-tools/bulletproof-gadgets?rev=4028605#402860539056639a3c22f243f8925bd4f89f869e" +source = "git+https://github.com/webb-tools/bulletproof-gadgets?branch=main#ea1981f241243def9a789fabfb9d41155613b599" dependencies = [ "bencher", "bulletproofs", "curve25519-dalek 3.0.2", - "hex", "merlin", - "num-bigint 0.3.2", "parity-scale-codec 1.3.7", "rand_core 0.5.1", "sp-std 2.0.1", @@ -1176,12 +1174,14 @@ dependencies = [ [[package]] name = "curve25519-gadgets" version = "2.0.0" -source = "git+https://github.com/webb-tools/bulletproof-gadgets?branch=main#ea1981f241243def9a789fabfb9d41155613b599" +source = "git+https://github.com/webb-tools/bulletproof-gadgets?rev=4028605#402860539056639a3c22f243f8925bd4f89f869e" dependencies = [ "bencher", "bulletproofs", "curve25519-dalek 3.0.2", + "hex", "merlin", + "num-bigint 0.3.2", "parity-scale-codec 1.3.7", "rand_core 0.5.1", "sp-std 2.0.1", diff --git a/pallets/mixer/src/lib.rs b/pallets/mixer/src/lib.rs index 47cdd4d0..097916df 100644 --- a/pallets/mixer/src/lib.rs +++ b/pallets/mixer/src/lib.rs @@ -55,11 +55,7 @@ mod benchmarking; pub mod weights; use codec::{Decode, Encode}; -use frame_support::{ - debug, dispatch, ensure, - traits::{Currency, ExistenceRequirement::AllowDeath, Get}, - weights::Weight, -}; +use frame_support::{debug, dispatch, ensure, traits::Get, weights::Weight}; use frame_system::ensure_signed; use merkle::{ utils::{ @@ -87,14 +83,13 @@ pub mod pallet { /// The pallet's configuration trait. #[pallet::config] - pub trait Config: frame_system::Config + merkle::Config { + pub trait Config: frame_system::Config + merkle::Config + orml_currencies::Config { #[pallet::constant] type ModuleId: Get; /// The overarching event type. type Event: IsType<::Event> + From>; /// Currency type for taking deposits - type Currency: Currency; - type MultiCurrency: MultiCurrency; + type Currency: MultiCurrency; /// The overarching group trait type Group: GroupTrait; /// The max depth of the mixers @@ -245,7 +240,7 @@ pub mod pallet { // get mixer info, should always exist if the module is initialized let mut mixer_info = Self::get_mixer(mixer_id)?; // ensure the sender has enough balance to cover deposit - let balance = T::Currency::free_balance(&sender); + let balance = T::Currency::free_balance(mixer_info.currency_id, &sender); // TODO: Multiplication by usize should be possible // using this hack for now, though we should optimise with regular // multiplication `data_points.len() * mixer_info.fixed_deposit_size` @@ -253,10 +248,10 @@ pub mod pallet { .iter() .map(|_| mixer_info.fixed_deposit_size) .fold(Zero::zero(), |acc, elt| acc + elt); - ensure!(balance >= deposit, Error::::InsufficientBalance); + // ensure!(balance >= deposit, Error::::InsufficientBalance); // transfer the deposit to the module - T::Currency::transfer(&sender, &Self::account_id(), deposit, AllowDeath)?; - // update the total value locked + // T::Currency::transfer(mixer_info.currency_id, &sender, &Self::account_id(), + // deposit)?; update the total value locked let tvl = Self::total_value_locked(mixer_id); >::insert(mixer_id, tvl + deposit); // add elements to the mixer group's merkle tree and save the leaves @@ -304,12 +299,12 @@ pub mod pallet { ScalarData::from_slice(&relayer.encode()), )?; // transfer the fixed deposit size to the sender - T::Currency::transfer( - &Self::account_id(), - &recipient, - mixer_info.fixed_deposit_size, - AllowDeath, - )?; + // T::Currency::transfer( + // mixer_info.currency_id, + // &Self::account_id(), + // &recipient, + // mixer_info.fixed_deposit_size, + // )?; // update the total value locked let tvl = Self::total_value_locked(withdraw_proof.mixer_id); >::insert(withdraw_proof.mixer_id, tvl - mixer_info.fixed_deposit_size); @@ -422,8 +417,10 @@ impl std::fmt::Debug for WithdrawProof { } } -/// Type alias for the balances_pallet::Balance type -pub type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; +/// Type alias for the orml_currencies::Balance type +type BalanceOf = <::Currency as MultiCurrency<::AccountId>>::Balance; +type CurrencyIdOf = <::Currency as MultiCurrency<::AccountId>>::CurrencyId; +type GetNativeCurrencyIdOf = ::GetNativeCurrencyId; /// Info about the mixer and it's leaf data #[derive(Encode, Decode, PartialEq)] @@ -437,6 +434,8 @@ pub struct MixerInfo { pub fixed_deposit_size: BalanceOf, /// All the leaves/deposits of the mixer pub leaves: Vec, + /// Id of the currency in the mixer + pub currency_id: CurrencyIdOf, } impl core::default::Default for MixerInfo { @@ -445,16 +444,23 @@ impl core::default::Default for MixerInfo { minimum_deposit_length_for_reward: Zero::zero(), fixed_deposit_size: Zero::zero(), leaves: Vec::new(), + currency_id: GetNativeCurrencyIdOf::::get(), } } } impl MixerInfo { - pub fn new(min_dep_length: T::BlockNumber, dep_size: BalanceOf, leaves: Vec) -> Self { + pub fn new( + min_dep_length: T::BlockNumber, + dep_size: BalanceOf, + leaves: Vec, + currency_id: CurrencyIdOf, + ) -> Self { Self { minimum_deposit_length_for_reward: min_dep_length, fixed_deposit_size: dep_size, leaves, + currency_id, } } } @@ -490,11 +496,8 @@ impl Module { // Creating a new merkle group and getting the id back let mixer_id: T::GroupId = T::Group::create_group(Self::account_id(), true, depth)?; // Creating mixer info data - let mixer_info = MixerInfo:: { - fixed_deposit_size: size, - minimum_deposit_length_for_reward: T::DepositLength::get(), - leaves: Vec::new(), - }; + let mixer_info = + MixerInfo::::new(T::DepositLength::get(), size, Vec::new(), T::GetNativeCurrencyId::get()); // Saving the mixer group to storage MixerGroups::::insert(mixer_id, mixer_info); mixer_ids.push(mixer_id); diff --git a/pallets/mixer/src/mock.rs b/pallets/mixer/src/mock.rs index a1360cd7..84549106 100644 --- a/pallets/mixer/src/mock.rs +++ b/pallets/mixer/src/mock.rs @@ -92,7 +92,6 @@ impl balances::Config for Test { parameter_type_with_key! { pub ExistentialDepositMap: |k: CurrencyId| -> Balance { match k { - 1 => 1, _ => 2, } }; @@ -135,7 +134,7 @@ parameter_types! { } impl Config for Test { - type Currency = Balances; + type Currency = Currencies; type DefaultAdmin = DefaultAdmin; type DepositLength = MinimumDepositLength; type Event = Event; @@ -143,7 +142,6 @@ impl Config for Test { type MaxMixerTreeDepth = MaxTreeDepth; type MixerSizes = MixerSizes; type ModuleId = MixerModuleId; - type MultiCurrency = Currencies; type WeightInfo = Weights; } From cb89954ceef4ba6fc5b36843fddba3256f572715 Mon Sep 17 00:00:00 2001 From: Filip Date: Thu, 11 Mar 2021 11:31:52 +0100 Subject: [PATCH 3/8] Added native currency id to config --- pallets/mixer/src/lib.rs | 32 +++++++++++++++++--------------- pallets/mixer/src/mock.rs | 1 + 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/pallets/mixer/src/lib.rs b/pallets/mixer/src/lib.rs index 097916df..1b1a7a0d 100644 --- a/pallets/mixer/src/lib.rs +++ b/pallets/mixer/src/lib.rs @@ -90,6 +90,8 @@ pub mod pallet { type Event: IsType<::Event> + From>; /// Currency type for taking deposits type Currency: MultiCurrency; + /// Native currency id + type NativeCurrencyId: Get>; /// The overarching group trait type Group: GroupTrait; /// The max depth of the mixers @@ -248,10 +250,10 @@ pub mod pallet { .iter() .map(|_| mixer_info.fixed_deposit_size) .fold(Zero::zero(), |acc, elt| acc + elt); - // ensure!(balance >= deposit, Error::::InsufficientBalance); + ensure!(balance >= deposit, Error::::InsufficientBalance); // transfer the deposit to the module - // T::Currency::transfer(mixer_info.currency_id, &sender, &Self::account_id(), - // deposit)?; update the total value locked + T::Currency::transfer(mixer_info.currency_id, &sender, &Self::account_id(), deposit)?; + // update the total value locked let tvl = Self::total_value_locked(mixer_id); >::insert(mixer_id, tvl + deposit); // add elements to the mixer group's merkle tree and save the leaves @@ -299,12 +301,12 @@ pub mod pallet { ScalarData::from_slice(&relayer.encode()), )?; // transfer the fixed deposit size to the sender - // T::Currency::transfer( - // mixer_info.currency_id, - // &Self::account_id(), - // &recipient, - // mixer_info.fixed_deposit_size, - // )?; + T::Currency::transfer( + mixer_info.currency_id, + &Self::account_id(), + &recipient, + mixer_info.fixed_deposit_size, + )?; // update the total value locked let tvl = Self::total_value_locked(withdraw_proof.mixer_id); >::insert(withdraw_proof.mixer_id, tvl - mixer_info.fixed_deposit_size); @@ -418,9 +420,10 @@ impl std::fmt::Debug for WithdrawProof { } /// Type alias for the orml_currencies::Balance type -type BalanceOf = <::Currency as MultiCurrency<::AccountId>>::Balance; -type CurrencyIdOf = <::Currency as MultiCurrency<::AccountId>>::CurrencyId; -type GetNativeCurrencyIdOf = ::GetNativeCurrencyId; +pub type BalanceOf = <::Currency as MultiCurrency<::AccountId>>::Balance; +pub type CurrencyIdOf = + <::Currency as orml_traits::MultiCurrency<::AccountId>>::CurrencyId; +pub type GetNativeCurrencyIdOf = ::GetNativeCurrencyId; /// Info about the mixer and it's leaf data #[derive(Encode, Decode, PartialEq)] @@ -444,7 +447,7 @@ impl core::default::Default for MixerInfo { minimum_deposit_length_for_reward: Zero::zero(), fixed_deposit_size: Zero::zero(), leaves: Vec::new(), - currency_id: GetNativeCurrencyIdOf::::get(), + currency_id: T::NativeCurrencyId::get(), } } } @@ -496,8 +499,7 @@ impl Module { // Creating a new merkle group and getting the id back let mixer_id: T::GroupId = T::Group::create_group(Self::account_id(), true, depth)?; // Creating mixer info data - let mixer_info = - MixerInfo::::new(T::DepositLength::get(), size, Vec::new(), T::GetNativeCurrencyId::get()); + let mixer_info = MixerInfo::::new(T::DepositLength::get(), size, Vec::new(), T::NativeCurrencyId::get()); // Saving the mixer group to storage MixerGroups::::insert(mixer_id, mixer_info); mixer_ids.push(mixer_id); diff --git a/pallets/mixer/src/mock.rs b/pallets/mixer/src/mock.rs index 84549106..c353f5e7 100644 --- a/pallets/mixer/src/mock.rs +++ b/pallets/mixer/src/mock.rs @@ -142,6 +142,7 @@ impl Config for Test { type MaxMixerTreeDepth = MaxTreeDepth; type MixerSizes = MixerSizes; type ModuleId = MixerModuleId; + type NativeCurrencyId = NativeCurrencyId; type WeightInfo = Weights; } From e1740c17d17b9f03353e14647e335dfd48762eb6 Mon Sep 17 00:00:00 2001 From: Filip Date: Thu, 11 Mar 2021 16:19:54 +0100 Subject: [PATCH 4/8] Runtime config, benchmark errors --- Cargo.lock | 3 ++ pallets/merkle/src/lib.rs | 2 +- pallets/mixer/src/benchmarking.rs | 48 +++++++++++++++++++------------ pallets/mixer/src/lib.rs | 11 +++---- pallets/mixer/src/mock.rs | 11 +++++-- runtime/Cargo.toml | 4 +++ runtime/src/lib.rs | 44 ++++++++++++++++++++++++++-- 7 files changed, 92 insertions(+), 31 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 92c939b8..f4dc81df 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3659,6 +3659,9 @@ dependencies = [ "frame-system-benchmarking", "frame-system-rpc-runtime-api", "hex-literal", + "orml-currencies", + "orml-tokens", + "orml-traits", "pallet-aura", "pallet-balances", "pallet-contracts", diff --git a/pallets/merkle/src/lib.rs b/pallets/merkle/src/lib.rs index 6696f5c9..b0b3c5fa 100644 --- a/pallets/merkle/src/lib.rs +++ b/pallets/merkle/src/lib.rs @@ -145,7 +145,7 @@ pub mod pallet { /// The pallet's configuration trait. #[pallet::config] - pub trait Config: frame_system::Config + balances::Config { + pub trait Config: frame_system::Config { /// The overarching event type. type Event: IsType<::Event> + From>; /// The overarching group ID type diff --git a/pallets/mixer/src/benchmarking.rs b/pallets/mixer/src/benchmarking.rs index 0f60dda8..8d2ffb48 100644 --- a/pallets/mixer/src/benchmarking.rs +++ b/pallets/mixer/src/benchmarking.rs @@ -1,16 +1,18 @@ use super::*; use bulletproofs::{r1cs::Prover, BulletproofGens, PedersenGens}; +use curve25519_dalek::scalar::Scalar; use curve25519_gadgets::fixed_deposit_tree::builder::FixedDepositTreeBuilder; use frame_benchmarking::{account, benchmarks, whitelisted_caller}; use frame_support::traits::OnFinalize; use frame_system::RawOrigin; use merkle::{default_hasher, utils::keys::ScalarData}; use merlin::Transcript; +use orml_traits::MultiCurrency; use sp_runtime::traits::Bounded; use crate::{Config, Module as Mixer}; use balances::Module as Balances; -use merkle::Module as Merkle; +use merkle::{Config as MerkleConfig, Module as Merkle}; const NUM_DEPOSITS: u32 = 10; const NUM_WITHDRAWALS: u32 = 5; @@ -23,8 +25,7 @@ benchmarks! { Mixer::::initialize().unwrap(); let mixer_id: T::GroupId = 0u32.into(); - // Adding initial balance to the `caller` in order to make the deposit - let _ = as Currency<_>>::make_free_balance_be(&caller, T::Balance::max_value()); + let currency_id: CurrencyIdOf = T::NativeCurrencyId::get(); // Making `d` leaves/data points let data_points = vec![ScalarData::zero(); d as usize]; @@ -36,12 +37,11 @@ benchmarks! { } withdraw { - let caller = whitelisted_caller(); + let caller: T::AccountId = whitelisted_caller(); Mixer::::initialize().unwrap(); let mixer_id: T::GroupId = 0u32.into(); - let balance = T::Balance::max_value(); - let _ = as Currency<_>>::make_free_balance_be(&caller, balance); + let balance: BalanceOf = 1_000_000_000u32.into(); let pc_gens = PedersenGens::default(); let poseidon = default_hasher(); @@ -50,7 +50,7 @@ benchmarks! { let prover = Prover::new(&pc_gens, &mut prover_transcript); let mut ftree = FixedDepositTreeBuilder::new() .hash_params(poseidon.clone()) - .depth(::MaxMixerTreeDepth::get().into()) + .depth(::MaxTreeDepth::get().into()) .build(); let leaf = ftree.generate_secrets(); @@ -59,27 +59,39 @@ benchmarks! { Mixer::::deposit(RawOrigin::Signed(caller.clone()).into(), mixer_id, vec![ScalarData(leaf)]).unwrap(); let root = Merkle::::get_merkle_root(mixer_id).unwrap(); - let (proof, (comms_cr, nullifier_hash, leaf_index_comms_cr, proof_comms_cr)) = - ftree.prove_zk(root.0, leaf, &ftree.hash_params.bp_gens, prover); + let (proof, (comms_cr, nullifier_hash, leaf_index_comms_cr, proof_comms_cr)) = ftree.prove_zk( + root.0, + leaf, + ScalarData::from_slice(&caller.encode()).to_scalar(), + ScalarData::from_slice(&caller.encode()).to_scalar(), + &ftree.hash_params.bp_gens, prover + ); let comms: Vec = comms_cr.iter().map(|x| Commitment(*x)).collect(); let leaf_index_comms: Vec = leaf_index_comms_cr.iter().map(|x| Commitment(*x)).collect(); let proof_comms: Vec = proof_comms_cr.iter().map(|x| Commitment(*x)).collect(); let block_number: T::BlockNumber = 0u32.into(); + + let withdraw_proof = WithdrawProof::::new( + mixer_id, + block_number, + root, + comms, + ScalarData(nullifier_hash), + proof.to_bytes(), + leaf_index_comms, + proof_comms, + None, + None + ); }: _( RawOrigin::Signed(caller.clone()), - mixer_id, - block_number, - root, - comms, - ScalarData(nullifier_hash), - proof.to_bytes(), - leaf_index_comms, - proof_comms + withdraw_proof ) verify { - let balance_after: T::Balance = as Currency<_>>::free_balance(&caller); + let currency_id: CurrencyIdOf = T::NativeCurrencyId::get(); + let balance_after: BalanceOf = T::Currency::free_balance(currency_id, &caller); assert_eq!(balance_after, balance); } diff --git a/pallets/mixer/src/lib.rs b/pallets/mixer/src/lib.rs index 1b1a7a0d..7890b0be 100644 --- a/pallets/mixer/src/lib.rs +++ b/pallets/mixer/src/lib.rs @@ -83,7 +83,7 @@ pub mod pallet { /// The pallet's configuration trait. #[pallet::config] - pub trait Config: frame_system::Config + merkle::Config + orml_currencies::Config { + pub trait Config: frame_system::Config + merkle::Config + orml_tokens::Config + orml_currencies::Config { #[pallet::constant] type ModuleId: Get; /// The overarching event type. @@ -91,12 +91,10 @@ pub mod pallet { /// Currency type for taking deposits type Currency: MultiCurrency; /// Native currency id + #[pallet::constant] type NativeCurrencyId: Get>; /// The overarching group trait type Group: GroupTrait; - /// The max depth of the mixers - #[pallet::constant] - type MaxMixerTreeDepth: Get; /// The small deposit length #[pallet::constant] type DepositLength: Get; @@ -422,8 +420,7 @@ impl std::fmt::Debug for WithdrawProof { /// Type alias for the orml_currencies::Balance type pub type BalanceOf = <::Currency as MultiCurrency<::AccountId>>::Balance; pub type CurrencyIdOf = - <::Currency as orml_traits::MultiCurrency<::AccountId>>::CurrencyId; -pub type GetNativeCurrencyIdOf = ::GetNativeCurrencyId; + <::Currency as MultiCurrency<::AccountId>>::CurrencyId; /// Info about the mixer and it's leaf data #[derive(Encode, Decode, PartialEq)] @@ -488,7 +485,7 @@ impl Module { let default_admin = T::DefaultAdmin::get(); // Initialize the admin in storage with default one Admin::::set(default_admin); - let depth: u8 = ::MaxMixerTreeDepth::get(); + let depth: u8 = ::MaxTreeDepth::get(); // Getting the sizes from the config let sizes = T::MixerSizes::get(); diff --git a/pallets/mixer/src/mock.rs b/pallets/mixer/src/mock.rs index c353f5e7..90a679a9 100644 --- a/pallets/mixer/src/mock.rs +++ b/pallets/mixer/src/mock.rs @@ -1,17 +1,18 @@ use super::*; use crate as pallet_mixer; +use frame_benchmarking::whitelisted_caller; use frame_support::{construct_runtime, parameter_types, weights::Weight}; use frame_system::mocking::{MockBlock, MockUncheckedExtrinsic}; use merkle::weights::Weights as MerkleWeights; use orml_currencies::BasicCurrencyAdapter; use orml_traits::parameter_type_with_key; -use pallet_mixer::weights::Weights; use sp_core::H256; use sp_runtime::{ testing::Header, traits::{BlakeTwo256, IdentityLookup}, ModuleId, Perbill, }; +use weights::Weights; pub(crate) type Balance = u64; pub type Amount = i128; @@ -139,7 +140,6 @@ impl Config for Test { type DepositLength = MinimumDepositLength; type Event = Event; type Group = MerkleGroups; - type MaxMixerTreeDepth = MaxTreeDepth; type MixerSizes = MixerSizes; type ModuleId = MixerModuleId; type NativeCurrencyId = NativeCurrencyId; @@ -154,7 +154,12 @@ pub fn new_test_ext() -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); BalancesConfig:: { // Total issuance will be 200 with treasury account initialized at ED. - balances: vec![(0, 1_000_000_000), (1, 1_000_000_000), (2, 1_000_000_000)], + balances: vec![ + (0, 1_000_000_000), + (1, 1_000_000_000), + (2, 1_000_000_000), + (whitelisted_caller(), 1_000_000_000), + ], } .assimilate_storage(&mut t) .unwrap(); diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml index 942f8cc1..af13e460 100644 --- a/runtime/Cargo.toml +++ b/runtime/Cargo.toml @@ -59,6 +59,10 @@ sp-std = { default-features = false, version = "3.0.0" } sp-transaction-pool = { default-features = false, version = "3.0.0" } sp-version = { default-features = false, version = "3.0.0" } +orml-tokens = { version = "0.4.0", default-features = false } +orml-currencies = { version = "0.4.0", default-features = false } +orml-traits = { version = "0.4.0", default-features = false } + [features] default = ["std"] runtime-benchmarks = [ diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 758138d3..8747c0c5 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -41,6 +41,9 @@ pub use frame_system::limits::{BlockLength, BlockWeights}; pub use pallet_balances::Call as BalancesCall; use pallet_contracts::weights::WeightInfo; pub use pallet_timestamp::Call as TimestampCall; + +use orml_currencies::BasicCurrencyAdapter; +use orml_traits::parameter_type_with_key; #[cfg(any(feature = "std", test))] pub use sp_runtime::BuildStorage; @@ -69,6 +72,11 @@ use mixer::weights::Weights as MixerWeights; /// An index to a block. pub type BlockNumber = u32; +// Currency id +pub type CurrencyId = u64; + +pub type Amount = i128; + /// Alias to 512-bit hash when used in the context of a transaction signature on /// the chain. pub type Signature = MultiSignature; @@ -333,6 +341,36 @@ impl merkle::Config for Runtime { type WeightInfo = MerkleWeights; } +parameter_type_with_key! { + pub ExistentialDepositMap: |k: CurrencyId| -> Balance { + match k { + _ => 2, + } + }; +} + +parameter_types! { + pub const NativeCurrencyId: CurrencyId = 0; +} + +impl orml_tokens::Config for Runtime { + type Amount = Amount; + type Balance = Balance; + type CurrencyId = CurrencyId; + type Event = Event; + type ExistentialDeposits = ExistentialDepositMap; + type OnDust = (); + type WeightInfo = (); +} + +impl orml_currencies::Config for Runtime { + type Event = Event; + type GetNativeCurrencyId = NativeCurrencyId; + type MultiCurrency = Tokens; + type NativeCurrency = BasicCurrencyAdapter; + type WeightInfo = (); +} + parameter_types! { pub const MixerModuleId: ModuleId = ModuleId(*b"py/mixer"); pub const MinimumDepositLength: BlockNumber = 10 * 60 * 24 * 28; @@ -346,14 +384,14 @@ parameter_types! { } impl mixer::Config for Runtime { - type Currency = Balances; + type Currency = Currencies; type DefaultAdmin = DefaultAdminKey; type DepositLength = MinimumDepositLength; type Event = Event; type Group = Merkle; - type MaxMixerTreeDepth = MaxTreeDepth; type MixerSizes = MixerSizes; type ModuleId = MixerModuleId; + type NativeCurrencyId = NativeCurrencyId; type WeightInfo = MixerWeights; } @@ -375,6 +413,8 @@ construct_runtime!( TransactionPayment: pallet_transaction_payment::{Module, Storage}, Sudo: pallet_sudo::{Module, Call, Config, Storage, Event}, + Currencies: orml_currencies::{Module, Storage, Event}, + Tokens: orml_tokens::{Module, Storage, Event}, Mixer: mixer::{Module, Call, Storage, Event}, Merkle: merkle::{Module, Call, Storage, Event}, } From fb34d5e417371e7baac40130c8429345b03438bd Mon Sep 17 00:00:00 2001 From: Filip Date: Thu, 11 Mar 2021 18:23:58 +0100 Subject: [PATCH 5/8] Testing mixer with non-native currency --- .github/workflows/build.yml | 54 ++++++++++----------- Cargo.lock | 3 ++ node/src/chain_spec.rs | 2 + pallets/merkle/src/tests.rs | 70 ++++++++++++++++++++++------ pallets/mixer/Cargo.toml | 1 + pallets/mixer/src/lib.rs | 17 +++++++ pallets/mixer/src/mock.rs | 19 ++++++-- pallets/mixer/src/tests.rs | 93 +++++++++++++++++++++++++++++++++++-- rustfmt.toml | 2 +- 9 files changed, 211 insertions(+), 50 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2e86903d..8b6ed3c8 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,38 +1,38 @@ -name: Set-Up & Build +name: Set-Up & Build & Test # Controls when the action will run. on: - push: - branches: - - "**" # matches every branch - - "!master" # excludes master - pull_request: - branches: - - "**" # matches every branch - - "!master" # excludes master - - # Allows you to run this workflow manually from the Actions tab - workflow_dispatch: + push: + branches: + - "**" # matches every branch + - "!master" # excludes master + pull_request: + branches: + - "**" # matches every branch + - "!master" # excludes master + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: # A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: - build: - # The type of runner that the job will run on - runs-on: ubuntu-18.04 + build: + # The type of runner that the job will run on + runs-on: ubuntu-18.04 - # Steps represent a sequence of tasks that will be executed as part of the job - steps: - # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - uses: actions/checkout@v2 + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - uses: actions/checkout@v2 - - name: Set-Up - run: sudo apt install -y cmake pkg-config libssl-dev git build-essential clang libclang-dev curl + - name: Set-Up + run: sudo apt install -y cmake pkg-config libssl-dev git build-essential clang libclang-dev curl - - name: Install Rustup - run: curl https://sh.rustup.rs -sSf | sh -s -- -y + - name: Install Rustup + run: curl https://sh.rustup.rs -sSf | sh -s -- -y - - name: Build - run: ./scripts/build.sh + - name: Build + run: ./scripts/build.sh - - name: Test - run: ./scripts/test.sh + - name: Test + run: ./scripts/test.sh diff --git a/Cargo.lock b/Cargo.lock index f4dc81df..833f497b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3859,6 +3859,7 @@ dependencies = [ "funty", "orml-traits", "parity-scale-codec 2.0.1", + "serde", "sp-runtime", "sp-std 3.0.0", ] @@ -3875,6 +3876,7 @@ dependencies = [ "num-traits", "orml-utilities", "parity-scale-codec 2.0.1", + "serde", "sp-io", "sp-runtime", "sp-std 3.0.0", @@ -3889,6 +3891,7 @@ dependencies = [ "frame-support", "funty", "parity-scale-codec 2.0.1", + "serde", "sp-io", "sp-runtime", "sp-std 3.0.0", diff --git a/node/src/chain_spec.rs b/node/src/chain_spec.rs index 853514b0..7a0d65d7 100644 --- a/node/src/chain_spec.rs +++ b/node/src/chain_spec.rs @@ -1,3 +1,4 @@ +use frame_benchmarking::whitelisted_caller; use node_template_runtime::{ AccountId, AuraConfig, BalancesConfig, GenesisConfig, GrandpaConfig, Signature, SudoConfig, SystemConfig, WASM_BINARY, @@ -59,6 +60,7 @@ pub fn development_config() -> Result { get_account_id_from_seed::("Bob"), get_account_id_from_seed::("Alice//stash"), get_account_id_from_seed::("Bob//stash"), + whitelisted_caller(), ], true, ) diff --git a/pallets/merkle/src/tests.rs b/pallets/merkle/src/tests.rs index 99c07f5a..3fc7308e 100644 --- a/pallets/merkle/src/tests.rs +++ b/pallets/merkle/src/tests.rs @@ -449,8 +449,14 @@ fn should_verify_simple_zk_proof_of_membership() { assert_ok!(MerkleGroups::add_members(Origin::signed(1), 0, vec![ScalarData(leaf)])); let root = MerkleGroups::get_merkle_root(0).unwrap(); - let (proof, (comms_cr, nullifier_hash, leaf_index_comms_cr, proof_comms_cr)) = - ftree.prove_zk(root.0, leaf, Scalar::zero(), Scalar::zero(), &ftree.hash_params.bp_gens, prover); + let (proof, (comms_cr, nullifier_hash, leaf_index_comms_cr, proof_comms_cr)) = ftree.prove_zk( + root.0, + leaf, + Scalar::zero(), + Scalar::zero(), + &ftree.hash_params.bp_gens, + prover, + ); let comms: Vec = comms_cr.iter().map(|x| Commitment(*x)).collect(); let leaf_index_comms: Vec = leaf_index_comms_cr.iter().map(|x| Commitment(*x)).collect(); @@ -489,8 +495,14 @@ fn should_not_verify_invalid_commitments_for_leaf_creation() { assert_ok!(MerkleGroups::add_members(Origin::signed(1), 0, vec![ScalarData(leaf)])); let root = MerkleGroups::get_merkle_root(0).unwrap(); - let (proof, (comms_cr, nullifier_hash, leaf_index_comms_cr, proof_comms_cr)) = - ftree.prove_zk(root.0, leaf, Scalar::zero(), Scalar::zero(), &ftree.hash_params.bp_gens, prover); + let (proof, (comms_cr, nullifier_hash, leaf_index_comms_cr, proof_comms_cr)) = ftree.prove_zk( + root.0, + leaf, + Scalar::zero(), + Scalar::zero(), + &ftree.hash_params.bp_gens, + prover, + ); let mut comms: Vec = comms_cr.iter().map(|x| Commitment(*x)).collect(); let mut rng = OsRng::default(); @@ -534,8 +546,14 @@ fn should_not_verify_invalid_private_inputs() { assert_ok!(MerkleGroups::add_members(Origin::signed(1), 0, vec![ScalarData(leaf)])); let root = MerkleGroups::get_merkle_root(0).unwrap(); - let (proof, (comms_cr, nullifier_hash, leaf_index_comms_cr, proof_comms_cr)) = - ftree.prove_zk(root.0, leaf, Scalar::zero(), Scalar::zero(), &ftree.hash_params.bp_gens, prover); + let (proof, (comms_cr, nullifier_hash, leaf_index_comms_cr, proof_comms_cr)) = ftree.prove_zk( + root.0, + leaf, + Scalar::zero(), + Scalar::zero(), + &ftree.hash_params.bp_gens, + prover, + ); let mut comms: Vec = comms_cr.iter().map(|x| Commitment(*x)).collect(); let leaf_index_comms: Vec = leaf_index_comms_cr.iter().map(|x| Commitment(*x)).collect(); @@ -581,8 +599,14 @@ fn should_not_verify_invalid_path_commitments_for_membership() { assert_ok!(MerkleGroups::add_members(Origin::signed(1), 0, vec![ScalarData(leaf)])); let root = MerkleGroups::get_merkle_root(0).unwrap(); - let (proof, (comms_cr, nullifier_hash, leaf_index_comms_cr, proof_comms_cr)) = - ftree.prove_zk(root.0, leaf, Scalar::zero(), Scalar::zero(), &ftree.hash_params.bp_gens, prover); + let (proof, (comms_cr, nullifier_hash, leaf_index_comms_cr, proof_comms_cr)) = ftree.prove_zk( + root.0, + leaf, + Scalar::zero(), + Scalar::zero(), + &ftree.hash_params.bp_gens, + prover, + ); let comms: Vec = comms_cr.iter().map(|x| Commitment(*x)).collect(); let mut leaf_index_comms: Vec = leaf_index_comms_cr.iter().map(|x| Commitment(*x)).collect(); @@ -627,8 +651,14 @@ fn should_not_verify_invalid_transcript() { assert_ok!(MerkleGroups::add_members(Origin::signed(1), 0, vec![ScalarData(leaf)])); let root = MerkleGroups::get_merkle_root(0).unwrap(); - let (proof, (comms_cr, nullifier_hash, leaf_index_comms_cr, proof_comms_cr)) = - ftree.prove_zk(root.0, leaf, Scalar::zero(), Scalar::zero(), &ftree.hash_params.bp_gens, prover); + let (proof, (comms_cr, nullifier_hash, leaf_index_comms_cr, proof_comms_cr)) = ftree.prove_zk( + root.0, + leaf, + Scalar::zero(), + Scalar::zero(), + &ftree.hash_params.bp_gens, + prover, + ); let comms: Vec = comms_cr.iter().map(|x| Commitment(*x)).collect(); let leaf_index_comms: Vec = leaf_index_comms_cr.iter().map(|x| Commitment(*x)).collect(); @@ -687,8 +717,14 @@ fn should_verify_zk_proof_of_membership() { assert_ok!(MerkleGroups::add_members(Origin::signed(1), 0, keys_data)); let root = MerkleGroups::get_merkle_root(0).unwrap(); - let (proof, (comms_cr, nullifier_hash, leaf_index_comms_cr, proof_comms_cr)) = - ftree.prove_zk(root.0, leaf5, Scalar::zero(), Scalar::zero(), &ftree.hash_params.bp_gens, prover); + let (proof, (comms_cr, nullifier_hash, leaf_index_comms_cr, proof_comms_cr)) = ftree.prove_zk( + root.0, + leaf5, + Scalar::zero(), + Scalar::zero(), + &ftree.hash_params.bp_gens, + prover, + ); let comms: Vec = comms_cr.iter().map(|x| Commitment(*x)).collect(); let leaf_index_comms: Vec = leaf_index_comms_cr.iter().map(|x| Commitment(*x)).collect(); @@ -725,8 +761,14 @@ fn should_verify_large_zk_proof_of_membership() { assert_ok!(MerkleGroups::add_members(Origin::signed(1), 0, vec![ScalarData(leaf)])); let root = MerkleGroups::get_merkle_root(0).unwrap(); - let (proof, (comms_cr, nullifier_hash, leaf_index_comms_cr, proof_comms_cr)) = - ftree.prove_zk(root.0, leaf, Scalar::zero(), Scalar::zero(), &ftree.hash_params.bp_gens, prover); + let (proof, (comms_cr, nullifier_hash, leaf_index_comms_cr, proof_comms_cr)) = ftree.prove_zk( + root.0, + leaf, + Scalar::zero(), + Scalar::zero(), + &ftree.hash_params.bp_gens, + prover, + ); let comms: Vec = comms_cr.iter().map(|x| Commitment(*x)).collect(); let leaf_index_comms: Vec = leaf_index_comms_cr.iter().map(|x| Commitment(*x)).collect(); diff --git a/pallets/mixer/Cargo.toml b/pallets/mixer/Cargo.toml index f737e80d..4f6b9fd4 100644 --- a/pallets/mixer/Cargo.toml +++ b/pallets/mixer/Cargo.toml @@ -57,6 +57,7 @@ std = [ "balances/std", "frame-support/std", "frame-system/std", + "orml-tokens/std", "frame-benchmarking/std", "merkle/std", ] diff --git a/pallets/mixer/src/lib.rs b/pallets/mixer/src/lib.rs index 7890b0be..826e2c78 100644 --- a/pallets/mixer/src/lib.rs +++ b/pallets/mixer/src/lib.rs @@ -80,6 +80,7 @@ pub mod pallet { use super::*; use frame_support::pallet_prelude::*; use frame_system::pallet_prelude::*; + use sp_runtime::DispatchResultWithInfo; /// The pallet's configuration trait. #[pallet::config] @@ -317,6 +318,22 @@ pub mod pallet { Ok(().into()) } + // NOTE: Used only for testing purposes + #[pallet::weight(0)] + pub fn create_new( + origin: OriginFor, + currency_id: CurrencyIdOf, + size: BalanceOf, + ) -> DispatchResultWithPostInfo { + ensure_admin(origin, &Self::admin())?; + + let depth: u8 = ::MaxTreeDepth::get(); + let mixer_id: T::GroupId = T::Group::create_group(Self::account_id(), true, depth)?; + let mixer_info = MixerInfo::::new(T::DepositLength::get(), size, Vec::new(), currency_id); + MixerGroups::::insert(mixer_id, mixer_info); + Ok(().into()) + } + /// Stops the operation of all the mixers managed by the pallet. /// Can only be called by the admin or the root origin. /// diff --git a/pallets/mixer/src/mock.rs b/pallets/mixer/src/mock.rs index 90a679a9..537d01d6 100644 --- a/pallets/mixer/src/mock.rs +++ b/pallets/mixer/src/mock.rs @@ -1,7 +1,7 @@ use super::*; use crate as pallet_mixer; use frame_benchmarking::whitelisted_caller; -use frame_support::{construct_runtime, parameter_types, weights::Weight}; +use frame_support::{construct_runtime, parameter_types, traits::GenesisBuild, weights::Weight}; use frame_system::mocking::{MockBlock, MockUncheckedExtrinsic}; use merkle::weights::Weights as MerkleWeights; use orml_currencies::BasicCurrencyAdapter; @@ -17,6 +17,7 @@ use weights::Weights; pub(crate) type Balance = u64; pub type Amount = i128; pub type CurrencyId = u64; +pub type AccountId = u64; pub type BlockNumber = u64; // Configure a mock runtime to test the pallet. @@ -34,7 +35,7 @@ construct_runtime!( MerkleGroups: merkle::{Module, Call, Storage, Event}, Mixer: pallet_mixer::{Module, Call, Storage, Event}, Currencies: orml_currencies::{Module, Storage, Event}, - Tokens: orml_tokens::{Module, Storage, Event}, + Tokens: orml_tokens::{Module, Storage, Event, Config}, } ); @@ -48,11 +49,11 @@ parameter_types! { impl frame_system::Config for Test { type AccountData = balances::AccountData; - type AccountId = u64; + type AccountId = AccountId; type BaseCallFilter = (); type BlockHashCount = BlockHashCount; type BlockLength = (); - type BlockNumber = u64; + type BlockNumber = BlockNumber; type BlockWeights = (); type Call = Call; type DbWeight = (); @@ -151,7 +152,9 @@ pub type MixerCall = pallet_mixer::Call; // Build genesis storage according to the mock runtime. pub fn new_test_ext() -> sp_io::TestExternalities { use balances::GenesisConfig as BalancesConfig; + use orml_tokens::GenesisConfig as TokensConfig; let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); + BalancesConfig:: { // Total issuance will be 200 with treasury account initialized at ED. balances: vec![ @@ -163,5 +166,13 @@ pub fn new_test_ext() -> sp_io::TestExternalities { } .assimilate_storage(&mut t) .unwrap(); + + let token_currency_id: CurrencyId = 1; + TokensConfig:: { + endowed_accounts: vec![(0, token_currency_id, 1_000_000_000)], + } + .assimilate_storage(&mut t) + .unwrap(); + t.into() } diff --git a/pallets/mixer/src/tests.rs b/pallets/mixer/src/tests.rs index 320722cf..4db09448 100644 --- a/pallets/mixer/src/tests.rs +++ b/pallets/mixer/src/tests.rs @@ -1,7 +1,7 @@ -use curve25519_dalek::scalar::Scalar; use super::*; -use crate::mock::{new_test_ext, Balances, MerkleGroups, Mixer, MixerCall, Origin, System, Test}; +use crate::mock::{new_test_ext, AccountId, Balances, MerkleGroups, Mixer, MixerCall, Origin, System, Test, Tokens}; use bulletproofs::{r1cs::Prover, BulletproofGens, PedersenGens}; +use curve25519_dalek::scalar::Scalar; use curve25519_gadgets::{ fixed_deposit_tree::builder::FixedDepositTreeBuilder, poseidon::{ @@ -212,8 +212,14 @@ fn should_withdraw_from_each_mixer_successfully() { assert_ok!(Mixer::deposit(Origin::signed(1), i, vec![ScalarData(leaf)])); let root = MerkleGroups::get_merkle_root(i).unwrap(); - let (proof, (comms_cr, nullifier_hash, leaf_index_comms_cr, proof_comms_cr)) = - ftree.prove_zk(root.0, leaf, Scalar::from(2u32), Scalar::zero(), &ftree.hash_params.bp_gens, prover); + let (proof, (comms_cr, nullifier_hash, leaf_index_comms_cr, proof_comms_cr)) = ftree.prove_zk( + root.0, + leaf, + Scalar::from(2u32), + Scalar::zero(), + &ftree.hash_params.bp_gens, + prover, + ); let comms: Vec = comms_cr.iter().map(|x| Commitment(*x)).collect(); let leaf_index_comms: Vec = leaf_index_comms_cr.iter().map(|x| Commitment(*x)).collect(); @@ -323,3 +329,82 @@ fn should_not_have_cache_once_cache_length_exceeded() { } }) } + +#[test] +fn should_make_mixer_with_non_native_token() { + new_test_ext().execute_with(|| { + let currency_id = 1; + assert_ok!(Mixer::initialize()); + assert_ok!(Mixer::create_new(Origin::signed(4), currency_id, 1_000)); + + let pc_gens = PedersenGens::default(); + let poseidon = default_hasher(16400); + + let group_tree_id = 4u32; + let sender: AccountId = 0; + let recipient: AccountId = 1; + let mut prover_transcript = Transcript::new(b"zk_membership_proof"); + let prover = Prover::new(&pc_gens, &mut prover_transcript); + let mut ftree = FixedDepositTreeBuilder::new() + .hash_params(poseidon.clone()) + .depth(32) + .build(); + + let leaf = ftree.generate_secrets(); + ftree.tree.add_leaves(vec![leaf.to_bytes()], None); + + // Getting native balance before deposit + let native_balance_before = Balances::free_balance(&sender); + assert_ok!(Mixer::deposit(Origin::signed(sender), group_tree_id, vec![ScalarData( + leaf + )])); + // Native balance after deposit, to make sure its not touched + let native_balance_after = Balances::free_balance(&sender); + assert_eq!(native_balance_before, native_balance_after); + + let root = MerkleGroups::get_merkle_root(group_tree_id).unwrap(); + let (proof, (comms_cr, nullifier_hash, leaf_index_comms_cr, proof_comms_cr)) = ftree.prove_zk( + root.0, + leaf, + Scalar::from(recipient), + Scalar::zero(), + &ftree.hash_params.bp_gens, + prover, + ); + + let comms: Vec = comms_cr.iter().map(|x| Commitment(*x)).collect(); + let leaf_index_comms: Vec = leaf_index_comms_cr.iter().map(|x| Commitment(*x)).collect(); + let proof_comms: Vec = proof_comms_cr.iter().map(|x| Commitment(*x)).collect(); + + let m = Mixer::get_mixer(group_tree_id).unwrap(); + let balance_before = Tokens::free_balance(currency_id, &recipient); + let native_balance_before = Balances::free_balance(&sender); + // check TVL after depositing + let tvl = Mixer::total_value_locked(group_tree_id); + assert_eq!(tvl, m.fixed_deposit_size); + // withdraw from another account + assert_ok!(Mixer::withdraw( + Origin::signed(recipient), + WithdrawProof::new( + group_tree_id, + 0, + root, + comms, + ScalarData(nullifier_hash), + proof.to_bytes(), + leaf_index_comms, + proof_comms, + Some(recipient), + Some(0), + ) + )); + let balance_after = Tokens::free_balance(currency_id, &recipient); + assert_eq!(balance_before + m.fixed_deposit_size, balance_after); + // Native balance after withdraw, to make sure its not changed + let native_balance_after = Balances::free_balance(&sender); + assert_eq!(native_balance_before, native_balance_after); + // ensure TVL is 0 after withdrawing + let tvl = Mixer::total_value_locked(group_tree_id); + assert_eq!(tvl, 0); + }); +} diff --git a/rustfmt.toml b/rustfmt.toml index 21c44996..135fbb5d 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -2,7 +2,7 @@ condense_wildcard_suffixes = true format_code_in_doc_comments = true max_width = 120 hard_tabs = true -merge_imports = true +imports_granularity="Crate" overflow_delimited_expr = true reorder_impl_items = true use_field_init_shorthand = true From 946ed20fde5ab14ea0936e947e2a45f87c806b7f Mon Sep 17 00:00:00 2001 From: Filip Date: Fri, 12 Mar 2021 21:40:43 +0100 Subject: [PATCH 6/8] Updated deps, remove wasm-utils --- Cargo.lock | 171 ++------ Cargo.toml | 1 - pallets/merkle/Cargo.toml | 10 +- pallets/merkle/src/benchmarking.rs | 2 +- pallets/merkle/src/lib.rs | 6 +- pallets/merkle/src/tests.rs | 4 +- pallets/mixer/Cargo.toml | 10 +- pallets/mixer/src/benchmarking.rs | 2 +- pallets/mixer/src/lib.rs | 4 +- pallets/mixer/src/tests.rs | 4 +- scripts/docs.sh | 4 +- scripts/init.sh | 7 +- scripts/test.sh | 5 +- wasm-utils/Cargo.toml | 46 --- wasm-utils/build.sh | 4 - wasm-utils/init.sh | 8 - wasm-utils/publish.sh | 4 - wasm-utils/src/lib.rs | 602 ----------------------------- wasm-utils/test.sh | 4 - 19 files changed, 64 insertions(+), 834 deletions(-) delete mode 100644 wasm-utils/Cargo.toml delete mode 100755 wasm-utils/build.sh delete mode 100755 wasm-utils/init.sh delete mode 100755 wasm-utils/publish.sh delete mode 100644 wasm-utils/src/lib.rs delete mode 100755 wasm-utils/test.sh diff --git a/Cargo.lock b/Cargo.lock index 833f497b..6d9f64c7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -451,16 +451,6 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" -[[package]] -name = "bitvec" -version = "0.17.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41262f11d771fd4a61aa3ce019fca363b4b6c282fca9da2a31186d3965a47a5c" -dependencies = [ - "either", - "radium 0.3.0", -] - [[package]] name = "bitvec" version = "0.20.2" @@ -468,7 +458,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f682656975d3a682daff957be4ddeb65d6ad656737cd821f2d00685ae466af1" dependencies = [ "funty", - "radium 0.6.2", + "radium", "tap", "wyz", ] @@ -607,23 +597,18 @@ dependencies = [ ] [[package]] -name = "bulletproofs" +name = "bulletproofs-gadgets" version = "2.0.0" -source = "git+https://github.com/edgeware-builders/bulletproofs?branch=main#679a440bacfe120aff8bd2594f1fe72378210468" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f730544daa13f48320a9be1bf804dd3544193f20a4194901317fd3ec354861fb" dependencies = [ - "byteorder", - "clear_on_drop", + "bencher", "curve25519-dalek 3.0.2", - "digest 0.9.0", "merlin", - "rand 0.7.3", + "parity-scale-codec 1.3.7", "rand_core 0.5.1", - "serde", - "serde_derive", - "sha3", "sp-std 2.0.1", - "subtle 2.4.0", - "thiserror", + "webb-bulletproofs", ] [[package]] @@ -824,16 +809,6 @@ dependencies = [ "cache-padded", ] -[[package]] -name = "console_error_panic_hook" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8d976903543e0c48546a91908f21588a680a8c8f984df9a5d69feccb2b2a211" -dependencies = [ - "cfg-if 0.1.10", - "wasm-bindgen", -] - [[package]] name = "constant_time_eq" version = "0.1.5" @@ -1157,36 +1132,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "curve25519-gadgets" -version = "2.0.0" -source = "git+https://github.com/webb-tools/bulletproof-gadgets?branch=main#ea1981f241243def9a789fabfb9d41155613b599" -dependencies = [ - "bencher", - "bulletproofs", - "curve25519-dalek 3.0.2", - "merlin", - "parity-scale-codec 1.3.7", - "rand_core 0.5.1", - "sp-std 2.0.1", -] - -[[package]] -name = "curve25519-gadgets" -version = "2.0.0" -source = "git+https://github.com/webb-tools/bulletproof-gadgets?rev=4028605#402860539056639a3c22f243f8925bd4f89f869e" -dependencies = [ - "bencher", - "bulletproofs", - "curve25519-dalek 3.0.2", - "hex", - "merlin", - "num-bigint 0.3.2", - "parity-scale-codec 1.3.7", - "rand_core 0.5.1", - "sp-std 2.0.1", -] - [[package]] name = "data-encoding" version = "2.3.2" @@ -1987,10 +1932,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" dependencies = [ "cfg-if 1.0.0", - "js-sys", "libc", "wasi 0.9.0+wasi-snapshot-preview1", - "wasm-bindgen", ] [[package]] @@ -2000,10 +1943,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c9495705279e7140bf035dde1f6e750c162df8b625267cd52cc44e0b156732c8" dependencies = [ "cfg-if 1.0.0", - "js-sys", "libc", "wasi 0.10.0+wasi-snapshot-preview1", - "wasm-bindgen", ] [[package]] @@ -3478,24 +3419,6 @@ dependencies = [ "winapi 0.3.9", ] -[[package]] -name = "mixer-client" -version = "0.0.1" -dependencies = [ - "bincode", - "bulletproofs", - "console_error_panic_hook", - "curve25519-dalek 3.0.2", - "curve25519-gadgets 2.0.0 (git+https://github.com/webb-tools/bulletproof-gadgets?rev=4028605)", - "getrandom 0.2.2", - "js-sys", - "merlin", - "rand 0.7.3", - "serde", - "wasm-bindgen", - "wasm-bindgen-test", -] - [[package]] name = "more-asserts" version = "0.2.1" @@ -3725,17 +3648,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "num-bigint" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d0a3d5e207573f948a9e5376662aa743a2ea13f7c50a554d7af443a73fbfeba" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - [[package]] name = "num-complex" version = "0.2.4" @@ -3763,7 +3675,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c000134b5dbf44adc5cb772486d335293351644b801551abe8f75c84cfa4aef" dependencies = [ "autocfg", - "num-bigint 0.2.6", + "num-bigint", "num-integer", "num-traits", ] @@ -4036,9 +3948,8 @@ dependencies = [ name = "pallet-merkle" version = "3.0.0" dependencies = [ - "bulletproofs", + "bulletproofs-gadgets", "curve25519-dalek 3.0.2", - "curve25519-gadgets 2.0.0 (git+https://github.com/webb-tools/bulletproof-gadgets?branch=main)", "frame-benchmarking 3.1.0", "frame-support", "frame-system", @@ -4052,6 +3963,7 @@ dependencies = [ "sp-io", "sp-runtime", "sp-std 3.0.0", + "webb-bulletproofs", ] [[package]] @@ -4059,9 +3971,8 @@ name = "pallet-mixer" version = "3.0.0" dependencies = [ "bencher", - "bulletproofs", + "bulletproofs-gadgets", "curve25519-dalek 3.0.2", - "curve25519-gadgets 2.0.0 (git+https://github.com/webb-tools/bulletproof-gadgets?branch=main)", "frame-benchmarking 3.1.0", "frame-support", "frame-system", @@ -4077,6 +3988,7 @@ dependencies = [ "sp-io", "sp-runtime", "sp-std 3.0.0", + "webb-bulletproofs", ] [[package]] @@ -4230,10 +4142,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4b26b16c7687c3075982af47719e481815df30bc544f7a6690763a25ca16e9d" dependencies = [ "arrayvec 0.5.2", - "bitvec 0.17.4", "byte-slice-cast 0.3.5", "parity-scale-codec-derive 1.2.3", - "serde", ] [[package]] @@ -4243,7 +4153,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0cd3dab59b5cf4bc81069ade0fc470341a1ef3ad5fa73e5a8943bed2ec12b2e8" dependencies = [ "arrayvec 0.5.2", - "bitvec 0.20.2", + "bitvec", "byte-slice-cast 1.0.0", "parity-scale-codec-derive 2.0.1", "serde", @@ -4855,12 +4765,6 @@ dependencies = [ "proc-macro2", ] -[[package]] -name = "radium" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "def50a86306165861203e7f84ecffbbdfdea79f0e51039b33de1e952358c47ac" - [[package]] name = "radium" version = "0.6.2" @@ -5553,7 +5457,7 @@ dependencies = [ "futures-timer 3.0.2", "log", "merlin", - "num-bigint 0.2.6", + "num-bigint", "num-rational", "num-traits", "parity-scale-codec 2.0.1", @@ -8114,8 +8018,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ee1280240b7c461d6a0071313e08f34a60b0365f14260362e5a2b17d1d31aa7" dependencies = [ "cfg-if 1.0.0", - "serde", - "serde_json", "wasm-bindgen-macro", ] @@ -8175,30 +8077,6 @@ version = "0.2.71" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7d6f8ec44822dd71f5f221a5847fb34acd9060535c1211b70a05844c0f6383b1" -[[package]] -name = "wasm-bindgen-test" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ea9e4f0050d5498a160e6b9d278a9699598e445b51dacd05598da55114c801a" -dependencies = [ - "console_error_panic_hook", - "js-sys", - "scoped-tls", - "wasm-bindgen", - "wasm-bindgen-futures", - "wasm-bindgen-test-macro", -] - -[[package]] -name = "wasm-bindgen-test-macro" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43f40402f495d92df6cdd0d329e7cc2580c8f99bcd74faff0e468923a764b7d4" -dependencies = [ - "proc-macro2", - "quote", -] - [[package]] name = "wasm-timer" version = "0.2.5" @@ -8458,6 +8336,27 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "webb-bulletproofs" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dcc103f95a2509aea2ca010f7f06b137bc4693cf57f39947937ae00d487266" +dependencies = [ + "byteorder", + "clear_on_drop", + "curve25519-dalek 3.0.2", + "digest 0.9.0", + "merlin", + "rand 0.7.3", + "rand_core 0.5.1", + "serde", + "serde_derive", + "sha3", + "sp-std 2.0.1", + "subtle 2.4.0", + "thiserror", +] + [[package]] name = "webpki" version = "0.21.4" diff --git a/Cargo.toml b/Cargo.toml index e4d7efda..b31d3c57 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,6 @@ members = [ "pallets/merkle", "pallets/mixer", "runtime", - "wasm-utils" ] [profile.dev.package] diff --git a/pallets/merkle/Cargo.toml b/pallets/merkle/Cargo.toml index edc527cf..25a0e970 100644 --- a/pallets/merkle/Cargo.toml +++ b/pallets/merkle/Cargo.toml @@ -18,7 +18,6 @@ sp-runtime = { default-features = false, version = "3.0.0" } merlin = { version = "2.0.0", default-features = false } sha2 = { version = "0.9.1", default-features = false } rand_core = { version = "0.5", default-features = false, features = ["alloc", "getrandom"] } -bulletproofs = { version = "2.0.0", branch = "main", git = "https://github.com/edgeware-builders/bulletproofs", default-features = false, features = ["yoloproofs"] } serde = { version = "1.0.101", optional = true, features = ["derive"] } sp-io = { default-features = false, version = "3.0.0" } frame-benchmarking = { default-features = false, version = "3.0.0", optional = true } @@ -35,10 +34,15 @@ version = "3.0.0" default-features = false features = ["u64_backend", "alloc"] -[dependencies.curve25519-gadgets] +[dependencies.bulletproofs] +version = "2.0.0" +package = "webb-bulletproofs" +default-features = false +features = ["yoloproofs"] + +[dependencies.bulletproofs-gadgets] branch = "main" version = "2.0.0" -git = "https://github.com/webb-tools/bulletproof-gadgets" default-features = false [dev-dependencies] diff --git a/pallets/merkle/src/benchmarking.rs b/pallets/merkle/src/benchmarking.rs index 30cc91f9..3565bae1 100644 --- a/pallets/merkle/src/benchmarking.rs +++ b/pallets/merkle/src/benchmarking.rs @@ -1,5 +1,5 @@ use super::*; -use curve25519_gadgets::poseidon::Poseidon_hash_2; +use bulletproofs_gadgets::poseidon::Poseidon_hash_2; use frame_benchmarking::{account, benchmarks, whitelisted_caller}; use frame_support::traits::OnFinalize; use frame_system::{Module as System, RawOrigin}; diff --git a/pallets/merkle/src/lib.rs b/pallets/merkle/src/lib.rs index b0b3c5fa..bc8b1e4e 100644 --- a/pallets/merkle/src/lib.rs +++ b/pallets/merkle/src/lib.rs @@ -95,9 +95,7 @@ use bulletproofs::{ r1cs::{R1CSProof, Verifier}, BulletproofGens, PedersenGens, }; -use codec::{Decode, Encode}; -use curve25519_dalek::scalar::Scalar; -use curve25519_gadgets::{ +use bulletproofs_gadgets::{ fixed_deposit_tree::mixer_verif_gadget, poseidon::{ allocate_statics_for_verifier, @@ -107,6 +105,8 @@ use curve25519_gadgets::{ smt::gen_zero_tree, utils::AllocatedScalar, }; +use codec::{Decode, Encode}; +use curve25519_dalek::scalar::Scalar; use frame_support::{dispatch, ensure, traits::Get, weights::Weight, Parameter}; use frame_system::ensure_signed; use merlin::Transcript; diff --git a/pallets/merkle/src/tests.rs b/pallets/merkle/src/tests.rs index 3fc7308e..41d82ce5 100644 --- a/pallets/merkle/src/tests.rs +++ b/pallets/merkle/src/tests.rs @@ -4,8 +4,7 @@ use crate::{ utils::keys::{Commitment, ScalarData}, }; use bulletproofs::{r1cs::Prover, BulletproofGens, PedersenGens}; -use curve25519_dalek::{ristretto::RistrettoPoint, scalar::Scalar}; -use curve25519_gadgets::{ +use bulletproofs_gadgets::{ fixed_deposit_tree::builder::FixedDepositTreeBuilder, poseidon::{ builder::{Poseidon, PoseidonBuilder}, @@ -13,6 +12,7 @@ use curve25519_gadgets::{ }, smt::gen_zero_tree, }; +use curve25519_dalek::{ristretto::RistrettoPoint, scalar::Scalar}; use frame_support::{assert_err, assert_ok, traits::UnfilteredDispatchable}; use frame_system::RawOrigin; use merlin::Transcript; diff --git a/pallets/mixer/Cargo.toml b/pallets/mixer/Cargo.toml index 4f6b9fd4..98d8be30 100644 --- a/pallets/mixer/Cargo.toml +++ b/pallets/mixer/Cargo.toml @@ -17,17 +17,21 @@ sp-std = { default-features = false, version = "3.0.0" } sp-runtime = { default-features = false, version = '3.0.0' } merkle = { package = "pallet-merkle", path = "../merkle", default-features = false } serde = { version = "1.0.101", optional = true, features = ["derive"] } -bulletproofs = { version = "2.0.0", branch = "main", git = "https://github.com/edgeware-builders/bulletproofs", default-features = false, features = ["yoloproofs"] } merlin = { version = "2.0.0", default-features = false } frame-benchmarking = { default-features = false, version = "3.0.0", optional = true } orml-traits = { version = "0.4.0", default-features = false } orml-currencies = { version = "0.4.0", default-features = false } orml-tokens = { version = "0.4.0", default-features = false } -[dependencies.curve25519-gadgets] +[dependencies.bulletproofs] +version = "2.0.0" +package = "webb-bulletproofs" +default-features = false +features = ["yoloproofs"] + +[dependencies.bulletproofs-gadgets] branch = "main" version = "2.0.0" -git = "https://github.com/webb-tools/bulletproof-gadgets" default-features = false # alias "parity-scale-code" to "codec" diff --git a/pallets/mixer/src/benchmarking.rs b/pallets/mixer/src/benchmarking.rs index 8d2ffb48..e0f4d49e 100644 --- a/pallets/mixer/src/benchmarking.rs +++ b/pallets/mixer/src/benchmarking.rs @@ -1,7 +1,7 @@ use super::*; use bulletproofs::{r1cs::Prover, BulletproofGens, PedersenGens}; +use bulletproofs_gadgets::fixed_deposit_tree::builder::FixedDepositTreeBuilder; use curve25519_dalek::scalar::Scalar; -use curve25519_gadgets::fixed_deposit_tree::builder::FixedDepositTreeBuilder; use frame_benchmarking::{account, benchmarks, whitelisted_caller}; use frame_support::traits::OnFinalize; use frame_system::RawOrigin; diff --git a/pallets/mixer/src/lib.rs b/pallets/mixer/src/lib.rs index 826e2c78..cc1663a0 100644 --- a/pallets/mixer/src/lib.rs +++ b/pallets/mixer/src/lib.rs @@ -373,6 +373,7 @@ pub mod pallet { } } +/// Proof data for withdrawal #[derive(Encode, Decode, PartialEq, Clone)] pub struct WithdrawProof { /// The mixer id this withdraw proof corresponds to @@ -434,8 +435,9 @@ impl std::fmt::Debug for WithdrawProof { } } -/// Type alias for the orml_currencies::Balance type +/// Type alias for the orml_traits::MultiCurrency::Balance type pub type BalanceOf = <::Currency as MultiCurrency<::AccountId>>::Balance; +/// Type alias for the orml_traits::MultiCurrency::CurrencyId type pub type CurrencyIdOf = <::Currency as MultiCurrency<::AccountId>>::CurrencyId; diff --git a/pallets/mixer/src/tests.rs b/pallets/mixer/src/tests.rs index 4db09448..a1a41646 100644 --- a/pallets/mixer/src/tests.rs +++ b/pallets/mixer/src/tests.rs @@ -1,14 +1,14 @@ use super::*; use crate::mock::{new_test_ext, AccountId, Balances, MerkleGroups, Mixer, MixerCall, Origin, System, Test, Tokens}; use bulletproofs::{r1cs::Prover, BulletproofGens, PedersenGens}; -use curve25519_dalek::scalar::Scalar; -use curve25519_gadgets::{ +use bulletproofs_gadgets::{ fixed_deposit_tree::builder::FixedDepositTreeBuilder, poseidon::{ builder::{Poseidon, PoseidonBuilder}, PoseidonSbox, }, }; +use curve25519_dalek::scalar::Scalar; use frame_support::{ assert_err, assert_ok, traits::{OnFinalize, UnfilteredDispatchable}, diff --git a/scripts/docs.sh b/scripts/docs.sh index f9cd96e5..1251c605 100755 --- a/scripts/docs.sh +++ b/scripts/docs.sh @@ -1,6 +1,4 @@ SCRIPTDIR=$PWD PALLET=${1:-"merkle"} -for d in $(ls -d ./pallets/$PALLET/) ; do - cd "$SCRIPTDIR/$d" && cargo doc --open --no-deps -done \ No newline at end of file +cd "$SCRIPTDIR/pallets/$PALLET/" && cargo doc --open --no-deps \ No newline at end of file diff --git a/scripts/init.sh b/scripts/init.sh index 18912797..e3da2e0f 100755 --- a/scripts/init.sh +++ b/scripts/init.sh @@ -21,9 +21,4 @@ else curl https://sh.rustup.rs -sSf | sh -s -- -y source $HOME/.cargo/env export PATH=$HOME/.cargo/bin:$PATH -fi - -rustup install nightly-2021-03-02 -rustup target add wasm32-unknown-unknown --toolchain nightly-2021-03-02 -rustup default nightly-2021-03-02 -curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh \ No newline at end of file +fi \ No newline at end of file diff --git a/scripts/test.sh b/scripts/test.sh index 492216ff..5644a466 100755 --- a/scripts/test.sh +++ b/scripts/test.sh @@ -4,7 +4,4 @@ SCRIPTDIR=$PWD # test each pallets tests for d in $(ls -d ./pallets/*/) ; do cd "$SCRIPTDIR/$d" && cargo test --features runtime-benchmarks -done - -# test wasm utils -cd "$SCRIPTDIR/wasm-utils" && ./test.sh \ No newline at end of file +done \ No newline at end of file diff --git a/wasm-utils/Cargo.toml b/wasm-utils/Cargo.toml deleted file mode 100644 index 6049f060..00000000 --- a/wasm-utils/Cargo.toml +++ /dev/null @@ -1,46 +0,0 @@ -[package] -name = "mixer-client" -version = "0.0.1" -authors = ["Webb "] -edition = "2018" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -wasm-bindgen = { version = "0.2.69", features = ["serde-serialize"] } -js-sys = "0.3.46" -console_error_panic_hook = "0.1.6" -rand = { version = "0.7", features = ["wasm-bindgen"] } -merlin = { version = "2.0.0", default-features = false } -getrandom = { version = "0.2", features = ["js"] } -serde = { version = "1", features = ["derive"] } -bincode = "1.3.2" - -[dependencies.bulletproofs] -branch = "main" -version = "2.0.0" -git = "https://github.com/edgeware-builders/bulletproofs" -default-features = false -features = ["yoloproofs", "std"] - -[dependencies.curve25519-gadgets] -rev = "4028605" -version = "2.0.0" -git = "https://github.com/webb-tools/bulletproof-gadgets" - -[dependencies.curve25519-dalek] -version = "3.0.0" -default-features = false -features = ["u64_backend", "alloc"] - -[lib] -crate-type = ["cdylib", "rlib"] - -[profile.release] -# This makes the compiled code faster and smaller, but it makes compiling slower, -# so it's only enabled in release mode. -lto = true - -[dev-dependencies] -wasm-bindgen-test = "0.3.20" - diff --git a/wasm-utils/build.sh b/wasm-utils/build.sh deleted file mode 100755 index da1f79bb..00000000 --- a/wasm-utils/build.sh +++ /dev/null @@ -1,4 +0,0 @@ -chmod +x init.sh -./init.sh - -wasm-pack build --out-name mixer-client diff --git a/wasm-utils/init.sh b/wasm-utils/init.sh deleted file mode 100755 index ae9b624e..00000000 --- a/wasm-utils/init.sh +++ /dev/null @@ -1,8 +0,0 @@ -if ! command -v wasm-pack &> /dev/null -then - echo "wasm-pack not be found" - echo "install wasm-pack..." - curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh -else - echo "wasm-pack exists" -fi \ No newline at end of file diff --git a/wasm-utils/publish.sh b/wasm-utils/publish.sh deleted file mode 100755 index 9abd21f9..00000000 --- a/wasm-utils/publish.sh +++ /dev/null @@ -1,4 +0,0 @@ -chmod +x init.sh -./init.sh - -wasm-pack publish \ No newline at end of file diff --git a/wasm-utils/src/lib.rs b/wasm-utils/src/lib.rs deleted file mode 100644 index 500e4dea..00000000 --- a/wasm-utils/src/lib.rs +++ /dev/null @@ -1,602 +0,0 @@ -#![allow(clippy::vec_init_then_push)] - -use bulletproofs::{r1cs::Prover, BulletproofGens, PedersenGens}; -use curve25519_dalek::scalar::Scalar; -use curve25519_gadgets::{ - self, - fixed_deposit_tree::builder::{FixedDepositTree, FixedDepositTreeBuilder}, - poseidon::{ - builder::{Poseidon, PoseidonBuilder}, - PoseidonSbox, - }, -}; -use js_sys::{Array, JsString, Map, Uint8Array}; -use merlin::Transcript; -use std::{collections::hash_map::HashMap, convert::TryInto}; -use wasm_bindgen::prelude::*; - -#[wasm_bindgen] -extern "C" { - #[wasm_bindgen(js_namespace = console)] - fn log(s: &str); - - #[wasm_bindgen(typescript_type = "MixerGroups")] - pub type MixerGroups; - - #[wasm_bindgen(typescript_type = "Leaves")] - pub type Leaves; -} - -#[wasm_bindgen(start)] -pub fn set_panic_hook() { - // `set_panic_hook`is called once during initialization - // we are printing useful errors when out code panics - console_error_panic_hook::set_once(); -} - -#[wasm_bindgen] -#[derive(Debug, PartialEq)] -#[repr(u32)] -pub enum OperationCode { - Unknown = 0, - // Invalid hex string length when decoding - InvalidHexLength = 1, - // Failed to parse hex string - HexParsingFailed = 2, - // Invalid number of note parts when decoding - InvalidNoteLength = 3, - // Invalid note prefix - InvalidNotePrefix = 4, - // Invalid note version - InvalidNoteVersion = 5, - // Invalid note id when parsing - InvalidNoteId = 6, - // Invalid note block number when parsing - InvalidNoteBlockNumber = 7, - // Invalid note secrets - InvalidNoteSecrets = 8, - // Unable to find merkle tree - MerkleTreeNotFound = 9, - // Failed serialization of passed params - // Error for failing to parse rust type into JsValue - SerializationFailed = 10, - // Failed deserialization of JsValue into rust type - DeserializationFailed = 11, -} - -#[wasm_bindgen] -pub struct PoseidonHasherOptions { - /// The size of the permutation, in field elements. - width: usize, - /// Number of full SBox rounds in beginning - pub full_rounds_beginning: Option, - /// Number of full SBox rounds in end - pub full_rounds_end: Option, - /// Number of partial rounds - pub partial_rounds: Option, - /// The desired (classical) security level, in bits. - pub security_bits: Option, - /// Bulletproof generators for proving/verifying (serialized) - #[wasm_bindgen(skip)] - pub bp_gens: Option, -} - -impl Default for PoseidonHasherOptions { - fn default() -> Self { - Self { - width: 6, - full_rounds_beginning: None, - full_rounds_end: None, - partial_rounds: None, - security_bits: None, - bp_gens: None, - } - } -} - -#[wasm_bindgen] -impl PoseidonHasherOptions { - #[wasm_bindgen(constructor)] - pub fn new() -> Self { - Self::default() - } - - #[wasm_bindgen(setter)] - pub fn set_bp_gens(&mut self, value: Uint8Array) { - let bp_gens: BulletproofGens = - bincode::deserialize(&value.to_vec()).unwrap_or_else(|_| BulletproofGens::new(16400, 1)); - self.bp_gens = Some(bp_gens); - } - - #[wasm_bindgen(getter)] - pub fn bp_gens(&self) -> Uint8Array { - let val = self.bp_gens.clone().unwrap_or_else(|| BulletproofGens::new(16400, 1)); - let serialized = bincode::serialize(&val).unwrap_or_else(|_| Vec::new()); - Uint8Array::from(serialized.as_slice()) - } -} - -#[wasm_bindgen] -pub struct PoseidonHasher { - inner: Poseidon, -} - -#[wasm_bindgen] -impl PoseidonHasher { - pub fn default() -> Self { - Self::with_options(Default::default()) - } - - #[wasm_bindgen(constructor)] - pub fn with_options(opts: PoseidonHasherOptions) -> Self { - // default pedersen genrators - let pc_gens = PedersenGens::default(); - let bp_gens = opts.bp_gens.clone().unwrap_or_else(|| BulletproofGens::new(16400, 1)); - - let inner = PoseidonBuilder::new(opts.width) - .sbox(PoseidonSbox::Exponentiation3) - .bulletproof_gens(bp_gens) - .pedersen_gens(pc_gens) - .build(); - Self { inner } - } -} - -impl OperationCode { - fn into_js(self) -> JsValue { - JsValue::from(self as u32) - } -} - -// Decodes hex string into byte array -pub fn decode_hex(s: &str) -> Result<[u8; 32], OperationCode> { - if s.len() != 64 { - return Err(OperationCode::InvalidHexLength); - } - let arr: Result, OperationCode> = (0..s.len()) - .step_by(2) - .map(|i| u8::from_str_radix(&s[i..i + 2], 16).map_err(|_| OperationCode::HexParsingFailed)) - .collect(); - let mut buf: [u8; 32] = [0u8; 32]; - buf.copy_from_slice(&arr?[..]); - Ok(buf) -} - -// Encodes byte array -pub fn encode_hex(bytes: [u8; 32]) -> String { - bytes.iter().map(|&b| format!("{:02x}", b)).collect() -} - -const NOTE_PREFIX: &str = "webb.mix"; -const VERSION: &str = "v1"; - -#[wasm_bindgen] -pub struct Mixer { - tree_map: HashMap<(String, u8), FixedDepositTree>, - poseidon: PoseidonHasher, -} - -impl Mixer { - fn get_tree_mut(&mut self, asset: String, id: u8) -> Result<&mut FixedDepositTree, OperationCode> { - self.tree_map - .get_mut(&(asset, id)) - .ok_or(OperationCode::MerkleTreeNotFound) - } - - fn get_tree(&self, asset: String, id: u8) -> Result<&FixedDepositTree, OperationCode> { - self.tree_map.get(&(asset, id)).ok_or(OperationCode::MerkleTreeNotFound) - } -} - -#[wasm_bindgen(typescript_custom_section)] -const MIXER_GROUP_OBJECT: &'static str = r#" -type MixerGroup = { asset: string; group_id: number; tree_depth: number; } -type MixerGroups = MixerGroup[]; -"#; - -#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)] -struct MixerGroup { - pub asset: String, - pub group_id: u8, - pub tree_depth: usize, -} - -#[wasm_bindgen(typescript_custom_section)] -const LEAVES: &'static str = r#"type Leaves = Array;"#; - -#[wasm_bindgen] -impl Mixer { - #[allow(clippy::boxed_local)] - #[wasm_bindgen(constructor)] - pub fn new(groups_js: MixerGroups, poseidon: PoseidonHasher) -> Result { - let groups = Array::from(&groups_js) - .iter() - .map(|v| v.into_serde()) - .collect::, _>>() - .map_err(|_| OperationCode::DeserializationFailed.into_js())?; - let mut tree_map = HashMap::new(); - for MixerGroup { - asset, - group_id, - tree_depth, - } in groups - { - tree_map.insert( - (asset, group_id), - FixedDepositTreeBuilder::new() - .hash_params(poseidon.inner.clone()) - .depth(tree_depth) - .build(), - ); - } - Ok(Mixer { tree_map, poseidon }) - } - - pub fn add_leaves( - &mut self, - asset: String, - id: u8, - leaves: Leaves, - target_root: Option, - ) -> Result<(), JsValue> { - let fixed_tree = self.get_tree_mut(asset, id).map_err(|e| e.into_js())?; - let leaves_bytes = Array::from(&leaves) - .to_vec() - .into_iter() - .map(|v| Uint8Array::new_with_byte_offset_and_length(&v, 0, 32)) - .map(|v| v.to_vec().try_into()) - .collect::, _>>() - .map_err(|_| OperationCode::DeserializationFailed.into_js())?; - let root = target_root - .map(|v| v.to_vec().try_into()) - .transpose() - .map_err(|_| OperationCode::DeserializationFailed.into_js())?; - fixed_tree.tree.add_leaves(leaves_bytes, root); - Ok(()) - } - - pub fn get_root(&self, asset: String, id: u8) -> Result { - let fixed_tree = self.get_tree(asset, id).map_err(|e| e.into_js())?; - Ok(Uint8Array::from(fixed_tree.tree.root.to_bytes().to_vec().as_slice())) - } - - // Generates a new note with random samples - // note has a format of: - // `webb.mix-[version]-[asset]-[mixed_id]-[block_number]-[r_hex][nullifier_hex]` - pub fn generate_note(&mut self, asset: String, id: u8, block_number: Option) -> Result { - let fixed_tree = self.get_tree_mut(asset.to_owned(), id).map_err(|e| e.into_js())?; - let leaf = fixed_tree.generate_secrets(); - let (r, nullifier, ..) = fixed_tree.get_secrets(leaf); - - let encoded_r = encode_hex(r.to_bytes()); - let encoded_nullifier = encode_hex(nullifier.to_bytes()); - let mut parts: Vec = Vec::new(); - parts.push(NOTE_PREFIX.to_string()); - parts.push(VERSION.to_string()); - parts.push(asset); - parts.push(format!("{}", id)); - if let Some(bn) = block_number { - parts.push(format!("{}", bn)); - } - parts.push(format!("{}{}", encoded_r, encoded_nullifier)); - let note = parts.join("-"); - let note_js = JsString::from(note); - - Ok(note_js) - } - - // Saving the note to the tree. - // First it checks if the note is in valid format, - // then decodes it and saves a note to a Merkle Client - // to be used for constructing the proof - // returns the note leaf that can be used to do a deposit. - pub fn save_note(&mut self, note_js: JsString) -> Result { - let note: String = note_js.into(); - - let parts: Vec<&str> = note.split('-').collect(); - let partial = parts.len() == 5; - let full = parts.len() == 6; - if !partial && !full { - return Err(OperationCode::InvalidNoteLength.into_js()); - } - - if parts[0] != NOTE_PREFIX { - return Err(OperationCode::InvalidNotePrefix.into_js()); - } - if parts[1] != VERSION { - return Err(OperationCode::InvalidNoteVersion.into_js()); - } - let asset: String = parts[2].to_string(); - let id = parts[3].parse().map_err(|_| OperationCode::InvalidNoteId.into_js())?; - let (_block_number, note_val) = match partial { - true => (None, parts[4]), - false => { - let bn = parts[4] - .parse::() - .map_err(|_| OperationCode::InvalidNoteBlockNumber.into_js())?; - (Some(bn), parts[5]) - } - }; - if note_val.len() != 128 { - return Err(OperationCode::InvalidNoteSecrets.into_js()); - } - if !self.tree_map.contains_key(&(asset.to_owned(), id)) { - return Err(OperationCode::InvalidNoteSecrets.into_js()); - } - - // Checking the validity - let r_bytes = decode_hex(¬e_val[..64]).map_err(|e| e.into_js())?; - let nullifier_bytes = decode_hex(¬e_val[64..]).map_err(|e| e.into_js())?; - - let tree = self.get_tree_mut(asset, id).map_err(|e| e.into_js())?; - let (r, nullifier, nullifier_hash, leaf) = tree.leaf_data_from_bytes(r_bytes, nullifier_bytes); - tree.add_secrets(leaf, r, nullifier, nullifier_hash); - Ok(Uint8Array::from(leaf.to_bytes().to_vec().as_slice())) - } - - // Generates zk proof - pub fn generate_proof(&self, asset: String, id: u8, root: Uint8Array, leaf: Uint8Array) -> Result { - let root_bytes: [u8; 32] = root - .to_vec() - .try_into() - .map_err(|_| OperationCode::DeserializationFailed.into_js())?; - let leaf_bytes: [u8; 32] = leaf - .to_vec() - .try_into() - .map_err(|_| OperationCode::DeserializationFailed.into_js())?; - let tree = self.get_tree(asset, id).map_err(|e| e.into_js())?; - let root = Scalar::from_bytes_mod_order(root_bytes); - let leaf = Scalar::from_bytes_mod_order(leaf_bytes); - - let pc_gens = PedersenGens::default(); - let bp_gens = self.poseidon.inner.bp_gens.clone(); - let mut prover_transcript = Transcript::new(b"zk_membership_proof"); - let prover = Prover::new(&pc_gens, &mut prover_transcript); - - let (proof, (comms, nullifier_hash, leaf_index_comms, proof_comms)) = - tree.prove_zk(root, leaf, &bp_gens, prover); - - let leaf_index_comms_js = Array::new(); - for com in leaf_index_comms { - let bit_js = JsValue::from_serde(&com.0).map_err(|_| OperationCode::SerializationFailed.into_js())?; - leaf_index_comms_js.push(&bit_js); - } - let proof_comms_js = Array::new(); - for com in proof_comms { - let node = JsValue::from_serde(&com.0).map_err(|_| OperationCode::SerializationFailed.into_js())?; - proof_comms_js.push(&node); - } - let comms_js = Array::new(); - for com in comms { - let val = JsValue::from_serde(&com.0).map_err(|_| OperationCode::SerializationFailed.into_js())?; - comms_js.push(&val); - } - - let nullifier_hash = JsValue::from_serde(&nullifier_hash.to_bytes()) - .map_err(|_| OperationCode::SerializationFailed.into_js())?; - let bytes = JsValue::from_serde(&proof.to_bytes()).map_err(|_| OperationCode::SerializationFailed.into_js())?; - - let map = Map::new(); - map.set(&JsValue::from_str("comms"), &comms_js); - map.set(&JsValue::from_str("nullifier_hash"), &nullifier_hash); - map.set(&JsValue::from_str("leaf_index_comms"), &leaf_index_comms_js); - map.set(&JsValue::from_str("proof_comms"), &proof_comms_js); - map.set(&JsValue::from_str("proof"), &bytes); - - Ok(map) - } -} - -#[cfg(test)] -mod tests { - use super::*; - use curve25519_gadgets::poseidon::Poseidon_hash_2; - use rand::rngs::OsRng; - use wasm_bindgen_test::*; - - wasm_bindgen_test_configure!(run_in_browser); - - #[wasm_bindgen_test] - fn should_encode_and_decode_hex() { - let mut rng = OsRng::default(); - let num = Scalar::random(&mut rng); - - let enc = encode_hex(num.to_bytes()); - let dec = decode_hex(&enc).unwrap(); - - assert!(dec == num.to_bytes()); - } - - #[wasm_bindgen_test] - fn should_return_proper_errors() { - let mixer_group = MixerGroup { - asset: String::from("EDG"), - group_id: 0, - tree_depth: 2, - }; - let groups = JsValue::from_serde(&[&mixer_group]).unwrap(); - let mut mixer = Mixer::new(MixerGroups::from(groups), PoseidonHasher::default()).unwrap(); - - let invalid_leaves = JsValue::from_serde(&[1]).unwrap(); - let leaf_res = mixer.add_leaves( - mixer_group.asset, - mixer_group.group_id, - Leaves::from(invalid_leaves), - None, - ); - assert_eq!(leaf_res.err().unwrap(), OperationCode::DeserializationFailed.into_js()); - - let invalid_asset = "foo".to_string(); - let tree_res = mixer.get_tree(invalid_asset, mixer_group.group_id); - assert_eq!(tree_res.err().unwrap(), OperationCode::MerkleTreeNotFound); - } - - #[wasm_bindgen_test] - fn should_have_correct_root() { - let mixer_group = MixerGroup { - asset: String::from("EDG"), - group_id: 0, - tree_depth: 2, - }; - let groups = JsValue::from_serde(&[&mixer_group]).unwrap(); - let mut mixer = Mixer::new(MixerGroups::from(groups), PoseidonHasher::default()).unwrap(); - let leaf1 = Scalar::from(1u32); - let leaf2 = Scalar::from(2u32); - let leaf3 = Scalar::from(3u32); - let zero = Scalar::zero(); - - let mut leaves = Vec::new(); - leaves.push(leaf1.to_bytes()); - leaves.push(leaf2.to_bytes()); - leaves.push(leaf3.to_bytes()); - mixer - .add_leaves( - mixer_group.asset.clone(), - mixer_group.group_id, - Leaves::from(JsValue::from_serde(&leaves).unwrap()), - None, - ) - .unwrap(); - let tree = mixer.get_tree(mixer_group.asset.clone(), mixer_group.group_id).unwrap(); - let node1 = Poseidon_hash_2(leaf1, leaf2, &tree.hash_params); - let node2 = Poseidon_hash_2(leaf3, zero, &tree.hash_params); - let root = Poseidon_hash_2(node1, node2, &tree.hash_params); - - let calc_root = mixer.get_root(mixer_group.asset.clone(), mixer_group.group_id).unwrap(); - let calc_root: [u8; 32] = calc_root.to_vec().try_into().unwrap(); - assert_eq!(calc_root, root.to_bytes()); - } - - #[wasm_bindgen_test] - fn should_generate_and_save_note() { - let mixer_group = MixerGroup { - asset: String::from("EDG"), - group_id: 0, - tree_depth: 2, - }; - let groups = JsValue::from_serde(&[&mixer_group]).unwrap(); - let mut mixer = Mixer::new(MixerGroups::from(groups), PoseidonHasher::default()).unwrap(); - let note_js = mixer - .generate_note(mixer_group.asset.clone(), mixer_group.group_id, None) - .unwrap(); - let leaf = mixer.save_note(note_js).unwrap(); - assert_eq!(leaf.to_vec().len(), 32); - } - - #[wasm_bindgen_test] - fn should_create_proof() { - let mixer_group = MixerGroup { - asset: String::from("EDG"), - group_id: 0, - tree_depth: 2, - }; - let groups = JsValue::from_serde(&[&mixer_group]).unwrap(); - let mut mixer = Mixer::new(MixerGroups::from(groups), PoseidonHasher::default()).unwrap(); - let tree = mixer - .get_tree_mut(mixer_group.asset.clone(), mixer_group.group_id) - .unwrap(); - let leaf1 = tree.generate_secrets(); - let leaf2 = Scalar::from(2u32); - let leaf3 = Scalar::from(3u32); - - let mut leaves = Vec::new(); - leaves.push(leaf1.to_bytes()); - leaves.push(leaf2.to_bytes()); - leaves.push(leaf3.to_bytes()); - - mixer - .add_leaves( - mixer_group.asset.clone(), - mixer_group.group_id, - Leaves::from(JsValue::from_serde(&leaves).unwrap()), - None, - ) - .unwrap(); - let root = mixer.get_root(mixer_group.asset.clone(), mixer_group.group_id).unwrap(); - - let secret = Uint8Array::from(leaf1.to_bytes().to_vec().as_slice()); - let proof = mixer - .generate_proof(mixer_group.asset.clone(), mixer_group.group_id, root, secret) - .unwrap(); - let comms = proof.get(&JsValue::from_str("comms")); - // let nullifier_hash = proof.get(&JsValue::from_str("nullifier_hash")); - let leaf_index_comms = proof.get(&JsValue::from_str("leaf_index_comms")); - let proof_comms = proof.get(&JsValue::from_str("proof_comms")); - // let proof = proof.get(&JsValue::from_str("proof")); - - let comms_arr = Array::from(&comms); - let leaf_index_comms_arr = Array::from(&leaf_index_comms); - let proof_comms_arr = Array::from(&proof_comms); - - assert_eq!(comms_arr.length(), 3); - assert_eq!(leaf_index_comms_arr.length(), 2); - assert_eq!(proof_comms_arr.length(), 2); - - // Left for debugging purposes - // assert_eq!(nullifier_hash, 0); - // assert_eq!(proof, 0); - } - - #[wasm_bindgen_test] - fn should_create_proof_with_older_target_root() { - let mixer_group = MixerGroup { - asset: String::from("EDG"), - group_id: 0, - tree_depth: 2, - }; - let groups = JsValue::from_serde(&[&mixer_group]).unwrap(); - let mut mixer = Mixer::new(MixerGroups::from(groups), PoseidonHasher::default()).unwrap(); - let tree = mixer - .get_tree_mut(mixer_group.asset.clone(), mixer_group.group_id) - .unwrap(); - let leaf1 = tree.generate_secrets(); - let leaf2 = Scalar::from(2u32); - let leaf3 = Scalar::from(3u32); - - let mut leaves = Vec::new(); - leaves.push(leaf1.to_bytes()); - leaves.push(leaf2.to_bytes()); - leaves.push(leaf3.to_bytes()); - - mixer - .add_leaves( - mixer_group.asset.clone(), - mixer_group.group_id, - Leaves::from(JsValue::from_serde(&leaves).unwrap()), - None, - ) - .unwrap(); - let root = mixer.get_root(mixer_group.asset.clone(), mixer_group.group_id).unwrap(); - leaves.clear(); // clear old values - leaves.push(Scalar::from(4u32).to_bytes()); - leaves.push(Scalar::from(5u32).to_bytes()); - leaves.push(Scalar::from(6u32).to_bytes()); - // Attempt to add more leaves even with older target root - mixer - .add_leaves( - mixer_group.asset.clone(), - mixer_group.group_id, - Leaves::from(JsValue::from_serde(&leaves).unwrap()), - Some(root.clone()), - ) - .unwrap(); - - let same_root = mixer.get_root(mixer_group.asset.clone(), mixer_group.group_id).unwrap(); - assert_eq!(root.to_vec(), same_root.to_vec()); - - let secret = Uint8Array::from(leaf1.to_bytes().to_vec().as_slice()); - let proof = mixer - .generate_proof(mixer_group.asset.clone(), mixer_group.group_id, root, secret) - .unwrap(); - let comms = proof.get(&JsValue::from_str("comms")); - let leaf_index_comms = proof.get(&JsValue::from_str("leaf_index_comms")); - let proof_comms = proof.get(&JsValue::from_str("proof_comms")); - let comms_arr = Array::from(&comms); - let leaf_index_comms_arr = Array::from(&leaf_index_comms); - let proof_comms_arr = Array::from(&proof_comms); - - assert_eq!(comms_arr.length(), 3); - assert_eq!(leaf_index_comms_arr.length(), 2); - assert_eq!(proof_comms_arr.length(), 2); - } -} diff --git a/wasm-utils/test.sh b/wasm-utils/test.sh deleted file mode 100755 index 8c9b5208..00000000 --- a/wasm-utils/test.sh +++ /dev/null @@ -1,4 +0,0 @@ -chmod +x init.sh -./init.sh - -wasm-pack test --chrome --headless \ No newline at end of file From 82fbe19a6276af982f5af95b35d7e8856fec3fef Mon Sep 17 00:00:00 2001 From: Filip Date: Mon, 15 Mar 2021 12:32:38 +0100 Subject: [PATCH 7/8] Using merkle from crates --- pallets/mixer/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pallets/mixer/Cargo.toml b/pallets/mixer/Cargo.toml index 98d8be30..45b0d75d 100644 --- a/pallets/mixer/Cargo.toml +++ b/pallets/mixer/Cargo.toml @@ -15,7 +15,7 @@ frame-support = { default-features = false, version = '3.0.0' } frame-system = { default-features = false, version = '3.0.0' } sp-std = { default-features = false, version = "3.0.0" } sp-runtime = { default-features = false, version = '3.0.0' } -merkle = { package = "pallet-merkle", path = "../merkle", default-features = false } +merkle = { package = "pallet-merkle", version = "3.0.0", default-features = false } serde = { version = "1.0.101", optional = true, features = ["derive"] } merlin = { version = "2.0.0", default-features = false } frame-benchmarking = { default-features = false, version = "3.0.0", optional = true } From 434a7b778f434927795d04320a08eb8008b49225 Mon Sep 17 00:00:00 2001 From: Filip Date: Mon, 15 Mar 2021 15:47:20 +0100 Subject: [PATCH 8/8] Return back to local merkle dep --- pallets/mixer/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pallets/mixer/Cargo.toml b/pallets/mixer/Cargo.toml index 45b0d75d..98d8be30 100644 --- a/pallets/mixer/Cargo.toml +++ b/pallets/mixer/Cargo.toml @@ -15,7 +15,7 @@ frame-support = { default-features = false, version = '3.0.0' } frame-system = { default-features = false, version = '3.0.0' } sp-std = { default-features = false, version = "3.0.0" } sp-runtime = { default-features = false, version = '3.0.0' } -merkle = { package = "pallet-merkle", version = "3.0.0", default-features = false } +merkle = { package = "pallet-merkle", path = "../merkle", default-features = false } serde = { version = "1.0.101", optional = true, features = ["derive"] } merlin = { version = "2.0.0", default-features = false } frame-benchmarking = { default-features = false, version = "3.0.0", optional = true }