From 695d3e0047766c4d9b7e63d92b3d41e54439727f Mon Sep 17 00:00:00 2001 From: Xavier Lau Date: Thu, 19 Nov 2020 16:23:40 +0800 Subject: [PATCH 1/8] add: lock assets --- frame/bridge/ethereum/backing/src/lib.rs | 73 +++++++++++++++++++----- 1 file changed, 59 insertions(+), 14 deletions(-) diff --git a/frame/bridge/ethereum/backing/src/lib.rs b/frame/bridge/ethereum/backing/src/lib.rs index 7110630c1d..551683dc40 100644 --- a/frame/bridge/ethereum/backing/src/lib.rs +++ b/frame/bridge/ethereum/backing/src/lib.rs @@ -16,14 +16,12 @@ mod types { pub type Balance = u128; pub type DepositId = U256; - pub type RingBalance = - <::RingCurrency as Currency<::AccountId>>::Balance; - #[cfg(feature = "std")] - pub type KtonBalance = - <::KtonCurrency as Currency<::AccountId>>::Balance; + pub type AccountId = ::AccountId; + pub type RingBalance = <::RingCurrency as Currency>>::Balance; + pub type KtonBalance = <::KtonCurrency as Currency>>::Balance; pub type EthereumReceiptProofThing = <::EthereumRelay as EthereumReceipt< - ::AccountId, + AccountId, RingBalance, >>::EthereumReceiptProofThing; } @@ -39,7 +37,7 @@ use frame_support::{ }; use frame_system::{ensure_root, ensure_signed}; use sp_runtime::{ - traits::{AccountIdConversion, SaturatedConversion, Saturating}, + traits::{AccountIdConversion, SaturatedConversion, Saturating, Zero}, DispatchError, DispatchResult, ModuleId, RuntimeDebug, }; #[cfg(not(feature = "std"))] @@ -55,7 +53,7 @@ use ethereum_primitives::{receipt::EthereumTransactionIndex, EthereumAddress, U2 use types::*; pub trait Trait: frame_system::Trait { - /// The backing's module id, used for deriving its sovereign account ID. + /// The ethereum backing module id, used for deriving its sovereign account ID. type ModuleId: Get; type Event: From> + Into<::Event>; @@ -81,15 +79,21 @@ impl WeightInfo for () {} decl_event! { pub enum Event where - ::AccountId, + ModuleId = [u8; 8], + AccountId = AccountId, RingBalance = RingBalance, + KtonBalance = KtonBalance, { - /// Some one redeem some *RING*. [account, amount, transaction index] + /// Someone redeem some *RING*. [account, amount, transaction index] RedeemRing(AccountId, Balance, EthereumTransactionIndex), - /// Some one redeem some *KTON*. [account, amount, transaction index] + /// Someone redeem some *KTON*. [account, amount, transaction index] RedeemKton(AccountId, Balance, EthereumTransactionIndex), - /// Some one redeem a deposit. [account, deposit id, amount, transaction index] + /// Someone redeem a deposit. [account, deposit id, amount, transaction index] RedeemDeposit(AccountId, DepositId, RingBalance, EthereumTransactionIndex), + /// Someone lock some *RING*. [module id, account, amount] + LockRing(ModuleId, AccountId, RingBalance), + /// Someone lock some *KTON*. [module id, account, amount] + LockKton(ModuleId, AccountId, KtonBalance), } } @@ -138,6 +142,10 @@ decl_storage! { pub KtonTokenAddress get(fn kton_token_address) config(): EthereumAddress; pub RedeemStatus get(fn redeem_status): bool = true; + + pub LockAssetEvents + get(fn lock_asset_events) + : Vec<::Event>; } add_extra_genesis { config(ring_locked): RingBalance; @@ -148,7 +156,6 @@ decl_storage! { &>::account_id(), T::RingCurrency::minimum_balance() + config.ring_locked, ); - let _ = T::KtonCurrency::make_free_balance_be( &>::account_id(), T::KtonCurrency::minimum_balance() + config.kton_locked, @@ -164,7 +171,7 @@ decl_module! { { type Error = Error; - /// The treasury's module id, used for deriving its sovereign account ID. + /// The ethereum backing module id, used for deriving its sovereign account ID. const ModuleId: ModuleId = T::ModuleId::get(); fn deposit_event() = default; @@ -188,6 +195,44 @@ decl_module! { } } + /// Lock some balances into the module account + /// which very similar to lock some assets into the contract on ethereum side + #[weight = 10_000_000] + pub fn lock( + origin, + #[compact] ring_value: RingBalance, + #[compact] kton_value: KtonBalance, + ) { + let user = ensure_signed(origin)?; + + if !ring_value.is_zero() { + let ring_to_lock = ring_value.min(T::RingCurrency::usable_balance(&user)); + + // Should never fail, usable balance will always keep account live + T::RingCurrency::transfer(&user, &Self::account_id(), ring_to_lock, KeepAlive)?; + + let raw_event = RawEvent::LockRing(T::ModuleId::get().0, user.clone(), ring_to_lock); + let module_event: ::Event = raw_event.clone().into(); + let system_event: ::Event = module_event.into(); + + >::append(system_event); + Self::deposit_event(raw_event); + } + if !kton_value.is_zero() { + let kton_to_lock = kton_value.min(T::KtonCurrency::usable_balance(&user)); + + // Should never fail, usable balance will always keep account live + T::KtonCurrency::transfer(&user, &Self::account_id(), kton_to_lock, KeepAlive)?; + + let raw_event = RawEvent::LockKton(T::ModuleId::get().0, user.clone(), kton_to_lock); + let module_event: ::Event = raw_event.clone().into(); + let system_event: ::Event = module_event.into(); + + >::append(system_event); + Self::deposit_event(RawEvent::LockKton(T::ModuleId::get().0, user, kton_to_lock)); + } + } + // --- Root Call --- /// Set a new ring redeem address. From 52f2a9f535f56191e71446127ea31f5dc8576806 Mon Sep 17 00:00:00 2001 From: Xavier Lau Date: Thu, 19 Nov 2020 16:27:44 +0800 Subject: [PATCH 2/8] remove: unnecessary clone --- frame/bridge/ethereum/backing/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frame/bridge/ethereum/backing/src/lib.rs b/frame/bridge/ethereum/backing/src/lib.rs index d387562d96..068a2867b6 100644 --- a/frame/bridge/ethereum/backing/src/lib.rs +++ b/frame/bridge/ethereum/backing/src/lib.rs @@ -226,12 +226,12 @@ decl_module! { // Should never fail, usable balance will always keep account live T::KtonCurrency::transfer(&user, &Self::account_id(), kton_to_lock, KeepAlive)?; - let raw_event = RawEvent::LockKton(T::ModuleId::get().0, user.clone(), kton_to_lock); + let raw_event = RawEvent::LockKton(T::ModuleId::get().0, user, kton_to_lock); let module_event: ::Event = raw_event.clone().into(); let system_event: ::Event = module_event.into(); >::append(system_event); - Self::deposit_event(RawEvent::LockKton(T::ModuleId::get().0, user, kton_to_lock)); + Self::deposit_event(raw_event); } } From bff9df4253bde6a00a6d90bf607b9c5810583f61 Mon Sep 17 00:00:00 2001 From: Xavier Lau Date: Fri, 20 Nov 2020 12:11:27 +0800 Subject: [PATCH 3/8] add: fee --- frame/bridge/ethereum/backing/src/lib.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/frame/bridge/ethereum/backing/src/lib.rs b/frame/bridge/ethereum/backing/src/lib.rs index 068a2867b6..7fc6e78985 100644 --- a/frame/bridge/ethereum/backing/src/lib.rs +++ b/frame/bridge/ethereum/backing/src/lib.rs @@ -44,7 +44,7 @@ use sp_runtime::{ }; #[cfg(not(feature = "std"))] use sp_std::borrow::ToOwned; -use sp_std::{convert::TryFrom, vec}; +use sp_std::{convert::TryFrom, prelude::*}; // --- darwinia --- use array_bytes::array_unchecked; use darwinia_support::{ @@ -206,12 +206,16 @@ decl_module! { #[compact] kton_value: KtonBalance, ) { let user = ensure_signed(origin)?; + let module_account = Self::account_id(); + + // 50 Ring for fee + // https://github.com/darwinia-network/darwinia-common/pull/377#issuecomment-730369387 + T::RingCurrency::transfer(&user, &module_account, 50_000_000_000.into(), KeepAlive)?; if !ring_value.is_zero() { let ring_to_lock = ring_value.min(T::RingCurrency::usable_balance(&user)); - // Should never fail, usable balance will always keep account live - T::RingCurrency::transfer(&user, &Self::account_id(), ring_to_lock, KeepAlive)?; + T::RingCurrency::transfer(&user, &module_account, ring_to_lock, KeepAlive)?; let raw_event = RawEvent::LockRing(T::ModuleId::get().0, user.clone(), ring_to_lock); let module_event: ::Event = raw_event.clone().into(); @@ -223,8 +227,7 @@ decl_module! { if !kton_value.is_zero() { let kton_to_lock = kton_value.min(T::KtonCurrency::usable_balance(&user)); - // Should never fail, usable balance will always keep account live - T::KtonCurrency::transfer(&user, &Self::account_id(), kton_to_lock, KeepAlive)?; + T::KtonCurrency::transfer(&user, &module_account, kton_to_lock, KeepAlive)?; let raw_event = RawEvent::LockKton(T::ModuleId::get().0, user, kton_to_lock); let module_event: ::Event = raw_event.clone().into(); From 22bd2eb1ede206a89cb9476acf4ac2cdecc68830 Mon Sep 17 00:00:00 2001 From: Xavier Lau Date: Fri, 20 Nov 2020 12:19:00 +0800 Subject: [PATCH 4/8] custom: advanced fee --- bin/node/runtime/pangolin/src/lib.rs | 2 ++ frame/bridge/ethereum/backing/src/lib.rs | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/bin/node/runtime/pangolin/src/lib.rs b/bin/node/runtime/pangolin/src/lib.rs index 61e6f5a6ed..1d3ccf9946 100644 --- a/bin/node/runtime/pangolin/src/lib.rs +++ b/bin/node/runtime/pangolin/src/lib.rs @@ -972,6 +972,7 @@ impl darwinia_crab_backing::Trait for Runtime { parameter_types! { pub const EthBackingModuleId: ModuleId = ModuleId(*b"da/ethbk"); + pub const AdvancedFee: Balance = 50 * COIN; } impl darwinia_ethereum_backing::Trait for Runtime { type ModuleId = EthBackingModuleId; @@ -981,6 +982,7 @@ impl darwinia_ethereum_backing::Trait for Runtime { type OnDepositRedeem = Staking; type RingCurrency = Ring; type KtonCurrency = Kton; + type AdvancedFee = AdvancedFee; type WeightInfo = (); } diff --git a/frame/bridge/ethereum/backing/src/lib.rs b/frame/bridge/ethereum/backing/src/lib.rs index 7fc6e78985..95788ad10d 100644 --- a/frame/bridge/ethereum/backing/src/lib.rs +++ b/frame/bridge/ethereum/backing/src/lib.rs @@ -70,6 +70,8 @@ pub trait Trait: frame_system::Trait { type KtonCurrency: LockableCurrency; + type AdvancedFee: Get>; + /// Weight information for the extrinsics in this pallet. type WeightInfo: WeightInfo; } @@ -210,7 +212,7 @@ decl_module! { // 50 Ring for fee // https://github.com/darwinia-network/darwinia-common/pull/377#issuecomment-730369387 - T::RingCurrency::transfer(&user, &module_account, 50_000_000_000.into(), KeepAlive)?; + T::RingCurrency::transfer(&user, &module_account, T::AdvancedFee::get(), KeepAlive)?; if !ring_value.is_zero() { let ring_to_lock = ring_value.min(T::RingCurrency::usable_balance(&user)); From 84dde9acde02d606608d5cf4f8356690d883158e Mon Sep 17 00:00:00 2001 From: Xavier Lau Date: Fri, 20 Nov 2020 13:05:26 +0800 Subject: [PATCH 5/8] fix: tests --- frame/bridge/ethereum/backing/src/mock.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/frame/bridge/ethereum/backing/src/mock.rs b/frame/bridge/ethereum/backing/src/mock.rs index dfa0e0db3c..3b28cb6133 100644 --- a/frame/bridge/ethereum/backing/src/mock.rs +++ b/frame/bridge/ethereum/backing/src/mock.rs @@ -85,6 +85,7 @@ macro_rules! decl_tests { type OnDepositRedeem = Staking; type RingCurrency = Ring; type KtonCurrency = Kton; + type AdvancedFee = (); type WeightInfo = (); } From dc5d38d21519e410fe320baaf9cd7ed16d15b8dc Mon Sep 17 00:00:00 2001 From: Xavier Lau Date: Mon, 23 Nov 2020 16:40:53 +0800 Subject: [PATCH 6/8] remove: module id from event --- frame/bridge/ethereum/backing/src/lib.rs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/frame/bridge/ethereum/backing/src/lib.rs b/frame/bridge/ethereum/backing/src/lib.rs index 95788ad10d..10ffa1067f 100644 --- a/frame/bridge/ethereum/backing/src/lib.rs +++ b/frame/bridge/ethereum/backing/src/lib.rs @@ -83,7 +83,6 @@ impl WeightInfo for () {} decl_event! { pub enum Event where - ModuleId = [u8; 8], AccountId = AccountId, RingBalance = RingBalance, KtonBalance = KtonBalance, @@ -94,10 +93,10 @@ decl_event! { RedeemKton(AccountId, Balance, EthereumTransactionIndex), /// Someone redeem a deposit. [account, deposit id, amount, transaction index] RedeemDeposit(AccountId, DepositId, RingBalance, EthereumTransactionIndex), - /// Someone lock some *RING*. [module id, account, amount] - LockRing(ModuleId, AccountId, RingBalance), - /// Someone lock some *KTON*. [module id, account, amount] - LockKton(ModuleId, AccountId, KtonBalance), + /// Someone lock some *RING*. [account, amount] + LockRing(AccountId, RingBalance), + /// Someone lock some *KTON*. [account, amount] + LockKton(AccountId, KtonBalance), } } @@ -219,7 +218,7 @@ decl_module! { T::RingCurrency::transfer(&user, &module_account, ring_to_lock, KeepAlive)?; - let raw_event = RawEvent::LockRing(T::ModuleId::get().0, user.clone(), ring_to_lock); + let raw_event = RawEvent::LockRing(user.clone(), ring_to_lock); let module_event: ::Event = raw_event.clone().into(); let system_event: ::Event = module_event.into(); @@ -231,7 +230,7 @@ decl_module! { T::KtonCurrency::transfer(&user, &module_account, kton_to_lock, KeepAlive)?; - let raw_event = RawEvent::LockKton(T::ModuleId::get().0, user, kton_to_lock); + let raw_event = RawEvent::LockKton(user, kton_to_lock); let module_event: ::Event = raw_event.clone().into(); let system_event: ::Event = module_event.into(); From c0a613317be5494a0a30296c751960805abf696e Mon Sep 17 00:00:00 2001 From: Xavier Lau Date: Mon, 23 Nov 2020 17:46:01 +0800 Subject: [PATCH 7/8] add: fee account --- bin/node/runtime/pangolin/src/lib.rs | 6 +++-- frame/bridge/ethereum/backing/src/lib.rs | 27 +++++++++++++++++++---- frame/bridge/ethereum/backing/src/mock.rs | 6 +++-- 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/bin/node/runtime/pangolin/src/lib.rs b/bin/node/runtime/pangolin/src/lib.rs index 1d3ccf9946..1d40fd4616 100644 --- a/bin/node/runtime/pangolin/src/lib.rs +++ b/bin/node/runtime/pangolin/src/lib.rs @@ -971,11 +971,13 @@ impl darwinia_crab_backing::Trait for Runtime { } parameter_types! { - pub const EthBackingModuleId: ModuleId = ModuleId(*b"da/ethbk"); + pub const EthereumBackingModuleId: ModuleId = ModuleId(*b"da/ethbk"); + pub const EthereumBackingFeeModuleId: ModuleId = ModuleId(*b"da/ethfe"): pub const AdvancedFee: Balance = 50 * COIN; } impl darwinia_ethereum_backing::Trait for Runtime { - type ModuleId = EthBackingModuleId; + type ModuleId = EthereumBackingModuleId; + type EthereumBackingFeeModuleId = EthereumBackingFeeModuleId; type Event = Event; type RedeemAccountId = AccountId; type EthereumRelay = EthereumRelay; diff --git a/frame/bridge/ethereum/backing/src/lib.rs b/frame/bridge/ethereum/backing/src/lib.rs index 10ffa1067f..32aad39169 100644 --- a/frame/bridge/ethereum/backing/src/lib.rs +++ b/frame/bridge/ethereum/backing/src/lib.rs @@ -58,6 +58,8 @@ pub trait Trait: frame_system::Trait { /// The ethereum backing module id, used for deriving its sovereign account ID. type ModuleId: Get; + type EthereumBackingFeeModuleId: Get; + type Event: From> + Into<::Event>; type RedeemAccountId: From<[u8; 32]> + Into; @@ -163,6 +165,10 @@ decl_storage! { &>::account_id(), T::KtonCurrency::minimum_balance() + config.kton_locked, ); + let _ = T::RingCurrency::make_free_balance_be( + &>::fee_account_id(), + T::RingCurrency::minimum_balance(), + ); }); } } @@ -179,6 +185,15 @@ decl_module! { fn deposit_event() = default; + fn on_runtime_upgrade() -> frame_support::weights::Weight { + let _ = T::RingCurrency::make_free_balance_be( + &>::fee_account_id(), + T::RingCurrency::minimum_balance(), + ); + + 0 + } + /// Redeem balances /// /// # @@ -207,16 +222,16 @@ decl_module! { #[compact] kton_value: KtonBalance, ) { let user = ensure_signed(origin)?; - let module_account = Self::account_id(); + let fee_account = Self::fee_account_id(); // 50 Ring for fee // https://github.com/darwinia-network/darwinia-common/pull/377#issuecomment-730369387 - T::RingCurrency::transfer(&user, &module_account, T::AdvancedFee::get(), KeepAlive)?; + T::RingCurrency::transfer(&user, &fee_account, T::AdvancedFee::get(), KeepAlive)?; if !ring_value.is_zero() { let ring_to_lock = ring_value.min(T::RingCurrency::usable_balance(&user)); - T::RingCurrency::transfer(&user, &module_account, ring_to_lock, KeepAlive)?; + T::RingCurrency::transfer(&user, &fee_account, ring_to_lock, KeepAlive)?; let raw_event = RawEvent::LockRing(user.clone(), ring_to_lock); let module_event: ::Event = raw_event.clone().into(); @@ -228,7 +243,7 @@ decl_module! { if !kton_value.is_zero() { let kton_to_lock = kton_value.min(T::KtonCurrency::usable_balance(&user)); - T::KtonCurrency::transfer(&user, &module_account, kton_to_lock, KeepAlive)?; + T::KtonCurrency::transfer(&user, &fee_account, kton_to_lock, KeepAlive)?; let raw_event = RawEvent::LockKton(user, kton_to_lock); let module_event: ::Event = raw_event.clone().into(); @@ -293,6 +308,10 @@ impl Module { T::ModuleId::get().into_account() } + pub fn fee_account_id() -> T::AccountId { + T::EthereumBackingFeeModuleId::get().into_account() + } + pub fn account_id_try_from_bytes(bytes: &[u8]) -> Result { ensure!(bytes.len() == 32, >::AddrLenMis); diff --git a/frame/bridge/ethereum/backing/src/mock.rs b/frame/bridge/ethereum/backing/src/mock.rs index 3b28cb6133..d3cc5f3a23 100644 --- a/frame/bridge/ethereum/backing/src/mock.rs +++ b/frame/bridge/ethereum/backing/src/mock.rs @@ -75,10 +75,12 @@ macro_rules! decl_tests { #[derive(Clone, PartialEq, Eq, Debug)] pub struct Test; parameter_types! { - pub const EthBackingModuleId: ModuleId = ModuleId(*b"da/backi"); + pub const EthereumBackingModuleId: ModuleId = ModuleId(*b"da/backi"); + pub const EthereumBackingFeeModuleId: ModuleId = ModuleId(*b"da/ethfe"): } impl Trait for Test { - type ModuleId = EthBackingModuleId; + type ModuleId = EthereumBackingModuleId; + type EthereumBackingFeeModuleId = EthereumBackingFeeModuleId; type Event = (); type RedeemAccountId = AccountId; type EthereumRelay = EthereumRelay; From a02568f0aa49ee96f081d3ea6ac577d8948617ae Mon Sep 17 00:00:00 2001 From: Xavier Lau Date: Mon, 23 Nov 2020 17:56:15 +0800 Subject: [PATCH 8/8] fix: typo --- bin/node/runtime/pangolin/src/lib.rs | 2 +- frame/bridge/ethereum/backing/src/mock.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/node/runtime/pangolin/src/lib.rs b/bin/node/runtime/pangolin/src/lib.rs index 1d40fd4616..23064477c9 100644 --- a/bin/node/runtime/pangolin/src/lib.rs +++ b/bin/node/runtime/pangolin/src/lib.rs @@ -972,7 +972,7 @@ impl darwinia_crab_backing::Trait for Runtime { parameter_types! { pub const EthereumBackingModuleId: ModuleId = ModuleId(*b"da/ethbk"); - pub const EthereumBackingFeeModuleId: ModuleId = ModuleId(*b"da/ethfe"): + pub const EthereumBackingFeeModuleId: ModuleId = ModuleId(*b"da/ethfe"); pub const AdvancedFee: Balance = 50 * COIN; } impl darwinia_ethereum_backing::Trait for Runtime { diff --git a/frame/bridge/ethereum/backing/src/mock.rs b/frame/bridge/ethereum/backing/src/mock.rs index d3cc5f3a23..830b283f16 100644 --- a/frame/bridge/ethereum/backing/src/mock.rs +++ b/frame/bridge/ethereum/backing/src/mock.rs @@ -76,7 +76,7 @@ macro_rules! decl_tests { pub struct Test; parameter_types! { pub const EthereumBackingModuleId: ModuleId = ModuleId(*b"da/backi"); - pub const EthereumBackingFeeModuleId: ModuleId = ModuleId(*b"da/ethfe"): + pub const EthereumBackingFeeModuleId: ModuleId = ModuleId(*b"da/ethfe"); } impl Trait for Test { type ModuleId = EthereumBackingModuleId;