Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: handle tranfer with appchain token #360

Merged
merged 2 commits into from
Oct 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion node/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = 'debio'
version = '2.2.0'
version = '2.2.2'
edition = '2021'
license = 'AGPL-3.0'
authors = ['DeBio Dev Team <[email protected]>']
Expand Down
7 changes: 6 additions & 1 deletion pallets/genetic-analysis-orders/benchmarking/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,8 @@ benchmarks! {
_genetic_analyst.services[0],
0,
T::Hashing::hash("0xhJ7TRe456FADD2726A132ABJK5RCc9E6fC5869F4".as_bytes()),
"DeBio Genetic Genetic Link".as_bytes().to_vec()
"DeBio Genetic Genetic Link".as_bytes().to_vec(),
None
)

cancel_genetic_analysis_order {
Expand Down Expand Up @@ -164,6 +165,7 @@ benchmarks! {
0,
T::Hashing::hash("0xhJ7TRe456FADD2726A132ABJK5RCc9E6fC5869F4".as_bytes()),
"DeBio Genetic Genetic Link".as_bytes().to_vec(),
None,
);

let _genetic_analysis_order_id_list = GeneticAnalysisOrders::<T>::genetic_analysis_orders_by_genetic_analyst_id(caller.clone())
Expand Down Expand Up @@ -230,6 +232,7 @@ benchmarks! {
0,
T::Hashing::hash("0xhJ7TRe456FADD2726A132ABJK5RCc9E6fC5869F4".as_bytes()),
"DeBio Genetic Genetic Link".as_bytes().to_vec(),
None,
);

let _genetic_analysis_order_id_list = GeneticAnalysisOrders::<T>::genetic_analysis_orders_by_genetic_analyst_id(caller.clone())
Expand Down Expand Up @@ -296,6 +299,7 @@ benchmarks! {
0,
T::Hashing::hash("0xhJ7TRe456FADD2726A132ABJK5RCc9E6fC5869F4".as_bytes()),
"DeBio Genetic Genetic Link".as_bytes().to_vec(),
None,
);

let _genetic_analysis_order_id_list = GeneticAnalysisOrders::<T>::genetic_analysis_orders_by_genetic_analyst_id(caller.clone())
Expand Down Expand Up @@ -380,6 +384,7 @@ benchmarks! {
0,
T::Hashing::hash("0xhJ7TRe456FADD2726A132ABJK5RCc9E6fC5869F4".as_bytes()),
"DeBio Genetic Genetic Link".as_bytes().to_vec(),
None,
);

let _genetic_analysis_order_id_list = GeneticAnalysisOrders::<T>::genetic_analysis_orders_by_genetic_analyst_id(caller.clone())
Expand Down
258 changes: 258 additions & 0 deletions pallets/genetic-analysis-orders/src/functions.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,258 @@
use crate::*;

use frame_support::{
dispatch::DispatchError,
sp_runtime::traits::SaturatedConversion,
traits::{fungibles, ExistenceRequirement},
};
use primitives_price_and_currency::CurrencyType;
use scale_info::prelude::string::String;

impl<T: Config> Pallet<T> {
pub fn generate_genetic_analysis_order_id(
customer_id: &T::AccountId,
service_id: &T::Hash,
) -> T::Hash {
let mut customer_id_bytes = customer_id.encode();
let mut service_id_bytes = service_id.encode();
let account_info = frame_system::Pallet::<T>::account(customer_id);
let mut nonce_bytes = account_info.nonce.encode();

customer_id_bytes.append(&mut service_id_bytes);
customer_id_bytes.append(&mut nonce_bytes);

let seed = &customer_id_bytes;
T::Hashing::hash(seed)
}

pub fn update_genetic_analysis_order_status(
genetic_analysis_order_id: &T::Hash,
status: GeneticAnalysisOrderStatus,
) -> Result<GeneticAnalysisOrderOf<T>, Error<T>> {
let genetic_analysis_order = GeneticAnalysisOrders::<T>::mutate(
genetic_analysis_order_id,
|genetic_analysis_order| match genetic_analysis_order {
None => None,
Some(genetic_analysis_order) => {
genetic_analysis_order.status = status;
genetic_analysis_order.updated_at = pallet_timestamp::Pallet::<T>::get();
Some(genetic_analysis_order.clone())
},
},
)
.ok_or(Error::<T>::GeneticAnalysisOrderNotFound)?;

Ok(genetic_analysis_order)
}

pub fn insert_genetic_analysis_order_to_storage(
genetic_analysis_order: &GeneticAnalysisOrderOf<T>,
) {
GeneticAnalysisOrders::<T>::insert(genetic_analysis_order.id, genetic_analysis_order);
LastGeneticAnalysisOrderByCustomer::<T>::insert(
&genetic_analysis_order.customer_id,
genetic_analysis_order.id,
);
Self::insert_genetic_analysis_order_id_into_genetic_analysis_orders_by_seller(
genetic_analysis_order,
);
Self::insert_genetic_analysis_order_id_into_pending_genetic_analysis_orders_by_seller(
genetic_analysis_order,
);
Self::insert_genetic_analysis_order_id_into_genetic_analysis_orders_by_customer(
genetic_analysis_order,
);
}

pub fn insert_genetic_analysis_order_id_into_genetic_analysis_orders_by_seller(
genetic_analysis_order: &GeneticAnalysisOrderOf<T>,
) {
match GeneticAnalysisOrdersBySeller::<T>::get(&genetic_analysis_order.seller_id) {
None => {
GeneticAnalysisOrdersBySeller::<T>::insert(
&genetic_analysis_order.seller_id,
vec![genetic_analysis_order.id],
);
},
Some(mut genetic_analysis_orders) => {
genetic_analysis_orders.push(genetic_analysis_order.id);
GeneticAnalysisOrdersBySeller::<T>::insert(
&genetic_analysis_order.seller_id,
genetic_analysis_orders,
);
},
}
}

pub fn insert_genetic_analysis_order_id_into_genetic_analysis_orders_by_customer(
genetic_analysis_order: &GeneticAnalysisOrderOf<T>,
) {
match GeneticAnalysisOrdersByCustomer::<T>::get(&genetic_analysis_order.customer_id) {
None => {
GeneticAnalysisOrdersByCustomer::<T>::insert(
&genetic_analysis_order.customer_id,
vec![genetic_analysis_order.id],
);
},
Some(mut genetic_analysis_orders) => {
genetic_analysis_orders.push(genetic_analysis_order.id);
GeneticAnalysisOrdersByCustomer::<T>::insert(
&genetic_analysis_order.customer_id,
genetic_analysis_orders,
);
},
}
}

pub fn insert_genetic_analysis_order_id_into_pending_genetic_analysis_orders_by_seller(
genetic_analysis_order: &GeneticAnalysisOrderOf<T>,
) {
match PendingGeneticAnalysisOrdersBySeller::<T>::get(&genetic_analysis_order.seller_id) {
None => {
PendingGeneticAnalysisOrdersBySeller::<T>::insert(
&genetic_analysis_order.seller_id,
vec![genetic_analysis_order.id],
);
},
Some(mut genetic_analysis_orders) => {
genetic_analysis_orders.push(genetic_analysis_order.id);
PendingGeneticAnalysisOrdersBySeller::<T>::insert(
&genetic_analysis_order.seller_id,
genetic_analysis_orders,
);
},
}
}

pub fn remove_genetic_analysis_order_id_from_pending_genetic_analysis_orders_by_seller(
seller_id: &T::AccountId,
genetic_analysis_order_id: &T::Hash,
) {
let mut genetic_analysis_orders =
PendingGeneticAnalysisOrdersBySeller::<T>::get(seller_id).unwrap_or_default();
genetic_analysis_orders.retain(|o_id| o_id != genetic_analysis_order_id);
PendingGeneticAnalysisOrdersBySeller::<T>::insert(seller_id, genetic_analysis_orders);
}

pub fn genetic_analysis_order_can_be_refunded(tracking_id: &TrackingId) -> bool {
match T::GeneticAnalysis::genetic_analysis_by_genetic_analysis_tracking_id(tracking_id) {
Some(genetic_analysis) => genetic_analysis.is_rejected(),
None => false,
}
}

pub fn do_transfer(
currency: &CurrencyType,
sender: &T::AccountId,
receiver: &T::AccountId,
amount: BalanceOf<T>,
keep_alive: bool,
asset_id: Option<u32>,
) -> Result<(), Error<T>> {
if currency == &CurrencyType::DBIO {
let existence = if keep_alive {
ExistenceRequirement::KeepAlive
} else {
ExistenceRequirement::AllowDeath
};

let result = CurrencyOf::<T>::transfer(sender, receiver, amount, existence);

if let Err(dispatch) = result {
return match dispatch {
DispatchError::Other(_) => Err(Error::<T>::Other),
DispatchError::CannotLookup => Err(Error::<T>::CannotLookup),
DispatchError::BadOrigin => Err(Error::<T>::BadOrigin),
DispatchError::TooManyConsumers => Err(Error::<T>::TooManyConsumers),
DispatchError::ConsumerRemaining => Err(Error::<T>::ConsumerRemaining),
DispatchError::NoProviders => Err(Error::<T>::NoProviders),
DispatchError::Token(_) => Err(Error::<T>::Token),
DispatchError::Arithmetic(_) => Err(Error::<T>::Arithmetic),
DispatchError::Module(_) => Err(Error::<T>::Other),
}
}
} else {
let asset_id = asset_id.ok_or(Error::<T>::AssetIdNotFound)?;
let result = <T::Assets as fungibles::Transfer<T::AccountId>>::transfer(
asset_id,
sender,
receiver,
amount.saturated_into(),
keep_alive,
);

if let Err(dispatch) = result {
return match dispatch {
DispatchError::Other(_) => Err(Error::<T>::Other),
DispatchError::CannotLookup => Err(Error::<T>::CannotLookup),
DispatchError::BadOrigin => Err(Error::<T>::BadOrigin),
DispatchError::TooManyConsumers => Err(Error::<T>::TooManyConsumers),
DispatchError::ConsumerRemaining => Err(Error::<T>::ConsumerRemaining),
DispatchError::NoProviders => Err(Error::<T>::NoProviders),
DispatchError::Token(_) => Err(Error::<T>::Token),
DispatchError::Arithmetic(_) => Err(Error::<T>::Arithmetic),
DispatchError::Module(_) => Err(Error::<T>::Module),
}
}
}

Ok(())
}

pub fn do_validate_asset_id(
currency: &CurrencyType,
asset_id: Option<u32>,
) -> Result<Option<u32>, Error<T>> {
if currency == &CurrencyType::DBIO {
return Ok(None)
}

let asset_id = asset_id.ok_or(Error::<T>::AssetIdNotFound)?;
let symbol = <T::Assets as fungibles::InspectMetadata<T::AccountId>>::symbol(&asset_id);
let str_symbol = String::from_utf8(symbol).map_err(|_| Error::<T>::AssetIdNotFound)?;

if currency.as_string().to_lowercase() != str_symbol.to_lowercase() {
return Err(Error::<T>::AssetIdNotFound)
}

Ok(Some(asset_id))
}

/// The injected pallet ID
pub fn get_pallet_id() -> AccountIdOf<T> {
T::PalletId::get().into_account()
}

/// The account ID that holds the funds
pub fn account_id() -> AccountIdOf<T> {
<PalletAccount<T>>::get().unwrap()
}

/// Is the balance sufficient for payment
pub fn is_balance_sufficient_for_payment(
account_id: &AccountIdOf<T>,
price: BalanceOf<T>,
) -> bool {
let balance = T::Currency::free_balance(account_id);
balance >= price
}

/// Is the pallet balance sufficient for transfer
pub fn is_pallet_balance_sufficient_for_transfer(price: BalanceOf<T>) -> bool {
let balance = T::Currency::free_balance(&Self::account_id());
balance >= price
}

/// Set current escrow amount
pub fn set_escrow_amount() {
TotalEscrowAmount::<T>::put(T::Currency::free_balance(&Self::account_id()));
}

// Get token identifier
pub fn asset_id(currency_type: &CurrencyType) -> Result<u32, Error<T>> {
currency_type
.to_asset_id()
.parse::<u32>()
.map_err(|_| Error::<T>::WrongAssetIdFormat)
}
}
Loading