From 82830062a2440dfcef80c25f1af3b17cf78332b7 Mon Sep 17 00:00:00 2001 From: Filip Date: Wed, 10 Mar 2021 21:54:45 +0100 Subject: [PATCH 1/6] 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/6] 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/6] 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/6] 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/6] 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 2035d31f1b91b27d6778c69a637f3a83cb08b3e0 Mon Sep 17 00:00:00 2001 From: Filip Date: Wed, 17 Mar 2021 19:18:13 +0100 Subject: [PATCH 6/6] Making create_new non-dispatchable --- pallets/mixer/src/lib.rs | 33 +++++++++++++++++---------------- pallets/mixer/src/tests.rs | 11 +++++++++-- pallets/mixer/src/traits.rs | 6 ++++++ 3 files changed, 32 insertions(+), 18 deletions(-) create mode 100644 pallets/mixer/src/traits.rs diff --git a/pallets/mixer/src/lib.rs b/pallets/mixer/src/lib.rs index 826e2c78..51ecbf6a 100644 --- a/pallets/mixer/src/lib.rs +++ b/pallets/mixer/src/lib.rs @@ -54,6 +54,8 @@ pub mod tests; mod benchmarking; pub mod weights; +pub mod traits; + use codec::{Decode, Encode}; use frame_support::{debug, dispatch, ensure, traits::Get, weights::Weight}; use frame_system::ensure_signed; @@ -70,6 +72,7 @@ use sp_runtime::{ ModuleId, }; use sp_std::prelude::*; +use traits::ExtendedMixer; use weights::WeightInfo; pub use pallet::*; @@ -318,22 +321,6 @@ 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. /// @@ -526,3 +513,17 @@ impl Module { Ok(()) } } + +impl ExtendedMixer, BalanceOf> for Pallet { + fn create_new( + account_id: T::AccountId, + currency_id: CurrencyIdOf, + size: BalanceOf, + ) -> Result<(), dispatch::DispatchError> { + 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(()) + } +} diff --git a/pallets/mixer/src/tests.rs b/pallets/mixer/src/tests.rs index 4db09448..41d7898e 100644 --- a/pallets/mixer/src/tests.rs +++ b/pallets/mixer/src/tests.rs @@ -1,5 +1,8 @@ use super::*; -use crate::mock::{new_test_ext, AccountId, Balances, MerkleGroups, Mixer, MixerCall, Origin, System, Test, Tokens}; +use crate::mock::{ + new_test_ext, AccountId, Balance, Balances, CurrencyId, MerkleGroups, Mixer, MixerCall, Origin, System, Test, + Tokens, +}; use bulletproofs::{r1cs::Prover, BulletproofGens, PedersenGens}; use curve25519_dalek::scalar::Scalar; use curve25519_gadgets::{ @@ -335,7 +338,11 @@ 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)); + assert_ok!(>::create_new( + 4, + currency_id, + 1_000 + )); let pc_gens = PedersenGens::default(); let poseidon = default_hasher(16400); diff --git a/pallets/mixer/src/traits.rs b/pallets/mixer/src/traits.rs new file mode 100644 index 00000000..6f5474c6 --- /dev/null +++ b/pallets/mixer/src/traits.rs @@ -0,0 +1,6 @@ +use frame_support::dispatch; + +pub trait ExtendedMixer { + fn create_new(account_id: AccountId, currency_id: CurrencyId, size: Balance) + -> Result<(), dispatch::DispatchError>; +}