git.delta.rocks / unique-network / refs/commits / c8be66f6b517

difftreelog

Merge pull request #14 from usetech-llc/feature/NFTPAR-109-110_contract_sponsoring

str-mv2020-11-06parents: #3f1f974 #1447327.patch.diff
in: master
Feature/nftpar 109 110 contract sponsoring

4 files changed

modifiedCargo.lockdiffbeforeafterboth
3737 "frame-support",3737 "frame-support",
3738 "frame-system",3738 "frame-system",
3739 "log",3739 "log",
3740 "pallet-contracts",
3740 "pallet-transaction-payment",3741 "pallet-transaction-payment",
3741 "parity-scale-codec",3742 "parity-scale-codec",
3742 "serde",3743 "serde",
modifiedpallets/nft/Cargo.tomldiffbeforeafterboth
73branch = 'v2.0.0_release'73branch = 'v2.0.0_release'
74optional = true74optional = true
75
76[dependencies.pallet-contracts]
77default-features = false
78git = 'https://github.com/usetech-llc/substrate.git'
79package = 'pallet-contracts'
80branch = 'v2.0.0_release'
81version = '2.0.0'
7582
76[features]83[features]
77default = ['std']84default = ['std']
modifiedpallets/nft/src/default_weights.rsdiffbeforeafterboth
92 .saturating_add(DbWeight::get().reads(2 as Weight))92 .saturating_add(DbWeight::get().reads(2 as Weight))
93 .saturating_add(DbWeight::get().writes(1 as Weight))93 .saturating_add(DbWeight::get().writes(1 as Weight))
94 }94 }
95 // fn enable_contract_sponsoring() -> Weight {
96 // (0 as Weight)
97 // .saturating_add(DbWeight::get().reads(1 as Weight))
98 // .saturating_add(DbWeight::get().writes(1 as Weight))
99 // }
95}100}
96101
modifiedpallets/nft/src/lib.rsdiffbeforeafterboth
28use sp_runtime::sp_std::prelude::Vec;28use sp_runtime::sp_std::prelude::Vec;
29use sp_runtime::{29use sp_runtime::{
30 traits::{30 traits::{
31 DispatchInfoOf, Dispatchable, PostDispatchInfoOf, SaturatedConversion, Saturating,31 DispatchInfoOf, Dispatchable, PostDispatchInfoOf, Saturating, SignedExtension, Zero,
32 SignedExtension, Zero,
33 },32 },
34 transaction_validity::{33 transaction_validity::{
35 InvalidTransaction, TransactionPriority, TransactionValidity, TransactionValidityError,34 InvalidTransaction, TransactionValidity, TransactionValidityError, ValidTransaction,
36 ValidTransaction,
37 },35 },
38 FixedPointOperand, FixedU128,36 FixedPointOperand, FixedU128,
39};37};
38use pallet_contracts::ContractAddressFor;
39use sp_runtime::traits::StaticLookup;
4040
41#[cfg(test)]41#[cfg(test)]
42mod mock;42mod mock;
203 fn approve() -> Weight;203 fn approve() -> Weight;
204 fn transfer_from() -> Weight;204 fn transfer_from() -> Weight;
205 fn set_offchain_schema() -> Weight;205 fn set_offchain_schema() -> Weight;
206 // fn enable_contract_sponsoring() -> Weight;
206}207}
207208
208pub trait Trait: system::Trait + Sized {209pub trait Trait: system::Trait + Sized + transaction_payment::Trait + pallet_contracts::Trait {
209 type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>;210 type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>;
210211
211 /// Weight information for extrinsics in this pallet.212 /// Weight information for extrinsics in this pallet.
257 pub FungibleTransferBasket get(fn fungible_transfer_basket): double_map hasher(blake2_128_concat) u64, hasher(blake2_128_concat) u64 => Vec<BasketItem<T::AccountId, T::BlockNumber>>;258 pub FungibleTransferBasket get(fn fungible_transfer_basket): double_map hasher(blake2_128_concat) u64, hasher(blake2_128_concat) u64 => Vec<BasketItem<T::AccountId, T::BlockNumber>>;
258 pub ReFungibleTransferBasket get(fn refungible_transfer_basket): double_map hasher(blake2_128_concat) u64, hasher(blake2_128_concat) u64 => T::BlockNumber;259 pub ReFungibleTransferBasket get(fn refungible_transfer_basket): double_map hasher(blake2_128_concat) u64, hasher(blake2_128_concat) u64 => T::BlockNumber;
259260
260 // Sponsorship261 // Contract Sponsorship and Ownership
261 pub ContractSponsor get(fn contract_sponsor): map hasher(identity) T::AccountId => T::AccountId;262 pub ContractOwner get(fn contract_owner): map hasher(identity) T::AccountId => T::AccountId;
262 pub UnconfirmedContractSponsor get(fn unconfirmed_contract_sponsor): map hasher(identity) T::AccountId => T::AccountId;263 pub ContractSelfSponsoring get(fn contract_self_sponsoring): map hasher(identity) T::AccountId => bool;
263 }264 }
264 add_extra_genesis {265 add_extra_genesis {
265 build(|config: &GenesisConfig<T>| {266 build(|config: &GenesisConfig<T>| {
1114 Ok(())1115 Ok(())
1115 } 1116 }
1117
1118 /// Enable smart contract self-sponsoring.
1119 ///
1120 /// # Permissions
1121 ///
1122 /// * Contract Owner
1123 ///
1124 /// # Arguments
1125 ///
1126 /// * contract address
1127 /// * enable flag
1128 ///
1129 #[weight = 0]
1130 pub fn enable_contract_sponsoring(
1131 origin,
1132 contract_address: T::AccountId,
1133 enable: bool
1134 ) -> DispatchResult {
1135 let sender = ensure_signed(origin)?;
1136 let mut is_owner = false;
1137 if <ContractOwner<T>>::contains_key(contract_address.clone()) {
1138 let owner = <ContractOwner<T>>::get(&contract_address);
1139 is_owner = sender == owner;
1140 }
1141 ensure!(is_owner, "Only contract owner may call this method");
1142
1143 <ContractSelfSponsoring<T>>::insert(contract_address, enable);
1144 Ok(())
1145 }
1146
1116 }1147 }
1117}1148}
1737/// Require the transactor pay for themselves and maybe include a tip to gain additional priority1768/// Require the transactor pay for themselves and maybe include a tip to gain additional priority
1738/// in the queue.1769/// in the queue.
1739#[derive(Encode, Decode, Clone, Eq, PartialEq)]1770#[derive(Encode, Decode, Clone, Eq, PartialEq)]
1740pub struct ChargeTransactionPayment<T: transaction_payment::Trait + Send + Sync>(1771pub struct ChargeTransactionPayment<T: Trait + Send + Sync>(
1741 #[codec(compact)] BalanceOf<T>,1772 #[codec(compact)] BalanceOf<T>
1742);1773);
17431774
1744impl<T: Trait + transaction_payment::Trait + Send + Sync> sp_std::fmt::Debug1775impl<T: Trait + Send + Sync> sp_std::fmt::Debug
1745 for ChargeTransactionPayment<T>1776 for ChargeTransactionPayment<T>
1746{1777{
1747 #[cfg(feature = "std")]1778 #[cfg(feature = "std")]
1754 }1785 }
1755}1786}
17561787
1757impl<T: Trait + transaction_payment::Trait + Send + Sync> ChargeTransactionPayment<T>1788impl<T: Trait + Send + Sync> ChargeTransactionPayment<T>
1758where1789where
1759 T::Call:1790 T::Call: Dispatchable<Info = DispatchInfo, PostInfo = PostDispatchInfo> + IsSubType<Call<T>> + IsSubType<pallet_contracts::Call<T>>,
1760 Dispatchable<Info = DispatchInfo, PostInfo = PostDispatchInfo> + IsSubType<Call<T>>,
1761 BalanceOf<T>: Send + Sync + FixedPointOperand,1791 BalanceOf<T>: Send + Sync + FixedPointOperand,
1762{1792{
17871817
1788 // Set fee based on call type. Creating collection costs 1 Unique.1818 // Set fee based on call type. Creating collection costs 1 Unique.
1789 // All other transactions have traditional fees so far1819 // All other transactions have traditional fees so far
1820 // let fee = match call.is_sub_type() {
1821 // Some(Call::create_collection(..)) => <BalanceOf<T>>::from(1_000_000_000),
1822 // _ => Self::traditional_fee(len, info, tip), // Flat fee model, use only for testing purposes
1823 // // _ => <BalanceOf<T>>::from(100)
1824 // };
1790 let fee = match call.is_sub_type() {1825 let fee = Self::traditional_fee(len, info, tip);
1791 Some(Call::create_collection(..)) => <BalanceOf<T>>::from(1_000_000_000),
1792 _ => Self::traditional_fee(len, info, tip), // Flat fee model, use only for testing purposes
1793 // _ => <BalanceOf<T>>::from(100)
1794 };
17951826
1796 // Determine who is paying transaction fee based on ecnomic model1827 // Determine who is paying transaction fee based on ecnomic model
1797 // Parse call to extract collection ID and access collection sponsor1828 // Parse call to extract collection ID and access collection sponsor
1798 let sponsor: T::AccountId = match call.is_sub_type() {1829 let mut sponsor: T::AccountId = match IsSubType::<Call<T>>::is_sub_type(call) {
1799 Some(Call::create_item(collection_id, _properties, _owner)) => {1830 Some(Call::create_item(collection_id, _properties, _owner)) => {
1800 <Collection<T>>::get(collection_id).sponsor1831 <Collection<T>>::get(collection_id).sponsor
1801 }1832 }
1864 _ => T::AccountId::default(),1895 _ => T::AccountId::default(),
1865 };1896 };
1897
1898 // Sponsor smart contracts
1899 sponsor = match IsSubType::<pallet_contracts::Call<T>>::is_sub_type(call) {
1900
1901 // On instantiation: set the contract owner
1902 Some(pallet_contracts::Call::instantiate(_endowment, _gas_limit, code_hash, data)) => {
1903
1904 let new_contract_address = <T as pallet_contracts::Trait>::DetermineContractAddress::contract_address_for(
1905 code_hash,
1906 &data,
1907 &who,
1908 );
1909 <ContractOwner<T>>::insert(new_contract_address.clone(), who.clone());
1910
1911 T::AccountId::default()
1912 },
1913
1914 // When the contract is called, check if the sponsoring is enabled and pay fees from contract endowment if it is
1915 Some(pallet_contracts::Call::call(dest, _value, _gas_limit, _data)) => {
1916
1917 let mut sp = T::AccountId::default();
1918 let called_contract: T::AccountId = T::Lookup::lookup((*dest).clone()).unwrap_or(T::AccountId::default());
1919 if <ContractSelfSponsoring<T>>::contains_key(called_contract.clone()) {
1920 if <ContractSelfSponsoring<T>>::get(called_contract.clone()) {
1921 sp = called_contract;
1922 }
1923 }
1924
1925 sp
1926 },
1927
1928 _ => sponsor,
1929 };
18661930
1867 let mut who_pays_fee: T::AccountId = sponsor.clone();1931 let mut who_pays_fee: T::AccountId = sponsor.clone();
1868 if sponsor == T::AccountId::default() {1932 if sponsor == T::AccountId::default() {
1891}1955}
1956
18921957
1893impl<T: Trait + transaction_payment::Trait + Send + Sync> SignedExtension1958impl<T: Trait + Send + Sync> SignedExtension
1894 for ChargeTransactionPayment<T>1959 for ChargeTransactionPayment<T>
1895where1960where
1896 BalanceOf<T>: Send + Sync + From<u64> + FixedPointOperand,1961 BalanceOf<T>: Send + Sync + From<u64> + FixedPointOperand,
1897 T::Call: Dispatchable<Info = DispatchInfo, PostInfo = PostDispatchInfo> + IsSubType<Call<T>>,1962 T::Call: Dispatchable<Info = DispatchInfo, PostInfo = PostDispatchInfo> + IsSubType<Call<T>> + IsSubType<pallet_contracts::Call<T>>,
1898{1963{
1899 const IDENTIFIER: &'static str = "ChargeTransactionPayment";1964 const IDENTIFIER: &'static str = "ChargeTransactionPayment";
1900 type AccountId = T::AccountId;1965 type AccountId = T::AccountId;
19121977
1913 fn validate(1978 fn validate(
1914 &self,1979 &self,
1915 who: &Self::AccountId,1980 _who: &Self::AccountId,
1916 call: &Self::Call,1981 _call: &Self::Call,
1917 info: &DispatchInfoOf<Self::Call>,1982 _info: &DispatchInfoOf<Self::Call>,
1918 len: usize,1983 _len: usize,
1919 ) -> TransactionValidity {1984 ) -> TransactionValidity {
1920 let (fee, _) = self.withdraw_fee(who, call, info, len)?;
1921
1922 let mut r = ValidTransaction::default();1985 Ok(ValidTransaction::default())
1923 // NOTE: we probably want to maximize the _fee (of any type) per weight unit_ here, which
1924 // will be a bit more than setting the priority to tip. For now, this is enough.
1925 r.priority = fee.saturated_into::<TransactionPriority>();
1926 Ok(r)
1927 }1986 }
19281987
1929 fn pre_dispatch(1988 fn pre_dispatch(