difftreelog
feat add tests
in: master
12 files changed
node/cli/src/chain_spec.rsdiffbeforeafterboth267pub fn development_config() -> DefaultChainSpec {267pub fn development_config() -> DefaultChainSpec {268 let mut properties = Map::new();268 let mut properties = Map::new();269 properties.insert("tokenSymbol".into(), default_runtime::TOKEN_SYMBOL.into());269 properties.insert("tokenSymbol".into(), default_runtime::TOKEN_SYMBOL.into());270 properties.insert("tokenDecimals".into(), 18.into());270 properties.insert("tokenDecimals".into(), default_runtime::DECIMALS.into());271 properties.insert(271 properties.insert(272 "ss58Format".into(),272 "ss58Format".into(),273 default_runtime::SS58Prefix::get().into(),273 default_runtime::SS58Prefix::get().into(),341pub fn local_testnet_config() -> DefaultChainSpec {341pub fn local_testnet_config() -> DefaultChainSpec {342 let mut properties = Map::new();342 let mut properties = Map::new();343 properties.insert("tokenSymbol".into(), default_runtime::TOKEN_SYMBOL.into());343 properties.insert("tokenSymbol".into(), default_runtime::TOKEN_SYMBOL.into());344 properties.insert("tokenDecimals".into(), 18.into());344 properties.insert("tokenDecimals".into(), default_runtime::DECIMALS.into());345 properties.insert(345 properties.insert(346 "ss58Format".into(),346 "ss58Format".into(),347 default_runtime::SS58Prefix::get().into(),347 default_runtime::SS58Prefix::get().into(),pallets/balances-adapter/src/erc.rsdiffbeforeafterboth383839#[solidity_interface(name = ERC20, events(ERC20Events), enum(derive(PreDispatch)), enum_attr(weight), expect_selector = 0x942e8b22)]39#[solidity_interface(name = ERC20, events(ERC20Events), enum(derive(PreDispatch)), enum_attr(weight), expect_selector = 0x942e8b22)]40impl<T: Config> NativeFungibleHandle<T> {40impl<T: Config> NativeFungibleHandle<T> {41 fn allowance(&self, owner: Address, spender: Address) -> Result<U256> {41 fn allowance(&self, _owner: Address, _spender: Address) -> Result<U256> {42 Ok(U256::zero())42 Ok(U256::zero())43 }43 }444445 // #[weight(<SelfWeightOf<T>>::approve())]45 // #[weight(<SelfWeightOf<T>>::approve())]46 fn approve(&mut self, caller: Caller, spender: Address, amount: U256) -> Result<bool> {46 fn approve(&mut self, _caller: Caller, _spender: Address, _amount: U256) -> Result<bool> {47 // self.consume_store_reads(1)?;47 // self.consume_store_reads(1)?;48 Err("Approve not supported now".into())48 Err("Approve not supported".into())49 }49 }505051 fn balance_of(&self, owner: Address) -> Result<U256> {51 fn balance_of(&self, owner: Address) -> Result<U256> {106 let to = T::CrossAccountId::from_eth(to);106 let to = T::CrossAccountId::from_eth(to);107 let amount = amount.try_into().map_err(|_| "amount overflow")?;107 let amount = amount.try_into().map_err(|_| "amount overflow")?;108108109 if from != to {109 if from != caller {110 return Err("no permission".into());110 return Err("no permission".into());111 }111 }112 // let budget = self112 // let budget = self171 let to = to.into_sub_cross_account::<T>()?;171 let to = to.into_sub_cross_account::<T>()?;172 let amount = amount.try_into().map_err(|_| "amount overflow")?;172 let amount = amount.try_into().map_err(|_| "amount overflow")?;173173174 if from != to {174 if from != caller {175 return Err("no permission".into());175 return Err("no permission".into());176 }176 }177177pallets/common/src/dispatch.rsdiffbeforeafterboth83 ///83 ///84 /// * `sender` - The owner of the collection.84 /// * `sender` - The owner of the collection.85 /// * `handle` - Collection handle.85 /// * `handle` - Collection handle.86 fn destroy(sender: T::CrossAccountId, handle: CollectionHandle<T>) -> DispatchResult;86 fn destroy(sender: T::CrossAccountId, collection_id: CollectionId) -> DispatchResult;878788 /// Get a specialized collection from the handle.88 /// Get a specialized collection from the handle.89 ///89 ///pallets/unique/src/lib.rsdiffbeforeafterboth1296 sender: T::CrossAccountId,1296 sender: T::CrossAccountId,1297 collection_id: CollectionId,1297 collection_id: CollectionId,1298 ) -> DispatchResult {1298 ) -> DispatchResult {1299 let collection = <CollectionHandle<T>>::try_get(collection_id)?;1300 collection.check_is_internal()?;13011302 T::CollectionDispatch::destroy(sender, collection)?;1299 T::CollectionDispatch::destroy(sender, collection_id)?;130313001304 // TODO: basket cleanup should be moved elsewhere1301 // TODO: basket cleanup should be moved elsewhere1305 // Maybe runtime dispatch.rs should perform it?1302 // Maybe runtime dispatch.rs should perform it?runtime/common/config/pallets/mod.rsdiffbeforeafterboth24 weights::CommonWeights,24 weights::CommonWeights,25 RelayChainBlockNumberProvider,25 RelayChainBlockNumberProvider,26 },26 },27 Runtime, RuntimeEvent, RuntimeCall, RuntimeOrigin, RUNTIME_NAME, TOKEN_SYMBOL, Balances,27 Runtime, RuntimeEvent, RuntimeCall, RuntimeOrigin, RUNTIME_NAME, TOKEN_SYMBOL, DECIMALS,28 Balances,28};29};29use frame_support::traits::{ConstU32, ConstU64, Currency};30use frame_support::traits::{ConstU32, ConstU64, Currency};535454parameter_types! {55parameter_types! {55 pub const CollectionCreationPrice: Balance = 2 * UNIQUE;56 pub const CollectionCreationPrice: Balance = 2 * UNIQUE;56 pub const Decimals: u8 = 32;57 pub const Decimals: u8 = DECIMALS;57 pub TreasuryAccountId: AccountId = TreasuryModuleId::get().into_account_truncating();58 pub TreasuryAccountId: AccountId = TreasuryModuleId::get().into_account_truncating();58 pub Name: String = RUNTIME_NAME.to_string();59 pub Name: String = RUNTIME_NAME.to_string();59 pub Symbol: String = TOKEN_SYMBOL.to_string();60 pub Symbol: String = TOKEN_SYMBOL.to_string();runtime/common/dispatch.rsdiffbeforeafterboth99 Ok(id)99 Ok(id)100 }100 }101101102 fn destroy(sender: T::CrossAccountId, collection: CollectionHandle<T>) -> DispatchResult {102 fn destroy(sender: T::CrossAccountId, collection_id: CollectionId) -> DispatchResult {103 let collection = <CollectionHandle<T>>::try_get(collection_id)?;104 collection.check_is_internal()?;105103 match collection.mode {106 match collection.mode {104 CollectionMode::ReFungible => {107 CollectionMode::ReFungible => {112 }115 }113 }116 }114 Ok(())117 Ok(())115 }118 }116119117 fn dispatch(collection_id: CollectionId) -> Result<Self, DispatchError> {120 fn dispatch(collection_id: CollectionId) -> Result<Self, DispatchError> {118 if collection_id == CollectionId(0) {121 if collection_id == CollectionId(0) {runtime/opal/src/lib.rsdiffbeforeafterboth454546pub const RUNTIME_NAME: &str = "opal";46pub const RUNTIME_NAME: &str = "opal";47pub const TOKEN_SYMBOL: &str = "OPL";47pub const TOKEN_SYMBOL: &str = "OPL";48pub const DECIMALS: u8 = 18;484949/// This runtime version.50/// This runtime version.50pub const VERSION: RuntimeVersion = RuntimeVersion {51pub const VERSION: RuntimeVersion = RuntimeVersion {runtime/quartz/src/lib.rsdiffbeforeafterboth48#[cfg(not(feature = "become-sapphire"))]48#[cfg(not(feature = "become-sapphire"))]49pub const RUNTIME_NAME: &str = "quartz";49pub const RUNTIME_NAME: &str = "quartz";50pub const TOKEN_SYMBOL: &str = "QTZ";50pub const TOKEN_SYMBOL: &str = "QTZ";51pub const DECIMALS: u8 = 18;515252/// This runtime version.53/// This runtime version.53pub const VERSION: RuntimeVersion = RuntimeVersion {54pub const VERSION: RuntimeVersion = RuntimeVersion {runtime/unique/src/lib.rsdiffbeforeafterboth454546pub const RUNTIME_NAME: &str = "unique";46pub const RUNTIME_NAME: &str = "unique";47pub const TOKEN_SYMBOL: &str = "UNQ";47pub const TOKEN_SYMBOL: &str = "UNQ";48pub const DECIMALS: u8 = 18;484949/// This runtime version.50/// This runtime version.50pub const VERSION: RuntimeVersion = RuntimeVersion {51pub const VERSION: RuntimeVersion = RuntimeVersion {tests/src/eth/nativeFungible.test.tsdiffbeforeafterboth15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.161617import {IKeyringPair} from '@polkadot/types/types';17import {IKeyringPair} from '@polkadot/types/types';18import {itEth, usingEthPlaygrounds} from './util';18import {expect, itEth, usingEthPlaygrounds} from './util';191920describe('NativeFungible: Plain calls', () => {20describe('NativeFungible: ERC20 calls', () => {21 let donor: IKeyringPair;21 let donor: IKeyringPair;22 let alice: IKeyringPair;23 let owner: IKeyringPair;242225 before(async function() {23 before(async function() {26 await usingEthPlaygrounds(async (helper, privateKey) => {24 await usingEthPlaygrounds(async (helper, privateKey) => {27 donor = await privateKey({url: import.meta.url});25 donor = await privateKey({url: import.meta.url});28 [alice, owner] = await helper.arrange.createAccounts([30n, 20n], donor);26 // [alice] = await helper.arrange.createAccounts([30n], donor);29 });27 });30 });28 });312932 itEth.skip('Can perform approve()', async ({helper}) => {30 itEth('approve()', async ({helper}) => {33 const owner = await helper.eth.createAccountWithBalance(donor);31 const owner = await helper.eth.createAccountWithBalance(donor);34 const spender = helper.eth.createAccount();32 const spender = helper.eth.createAccount();35 const collection = await helper.ft.mintCollection(alice);36 await collection.mint(alice, 200n, {Ethereum: owner});3738 const collectionAddress = helper.ethAddress.fromCollectionId(0);33 const collectionAddress = helper.ethAddress.fromCollectionId(0);39 const contract = await helper.ethNativeContract.collection(collectionAddress, 'ft', owner);34 const contract = await helper.ethNativeContract.collection(collectionAddress, 'ft', owner);403541 await contract.methods.approve(spender, 100).send({from: owner});36 await expect(contract.methods.approve(spender, 100).call({from: owner})).to.be.rejectedWith('Approve not supported');42 });37 });3839 itEth('balanceOf()', async ({helper}) => {40 const owner = await helper.eth.createAccountWithBalance(donor, 123n);41 const collectionAddress = helper.ethAddress.fromCollectionId(0);42 const contract = await helper.ethNativeContract.collection(collectionAddress, 'ft', owner);4344 const balance = await contract.methods.balanceOf(owner).call({from: owner});45 expect(balance).to.be.eq('123000000000000000000');46 });4748 itEth('decimals()', async ({helper}) => {49 const owner = await helper.eth.createAccountWithBalance(donor);50 const collectionAddress = helper.ethAddress.fromCollectionId(0);51 const contract = await helper.ethNativeContract.collection(collectionAddress, 'ft', owner);5253 const decimals = await contract.methods.decimals().call({from: owner});54 expect(decimals).to.be.eq('18');55 });5657 itEth('name()', async ({helper}) => {58 const owner = await helper.eth.createAccountWithBalance(donor);59 const collectionAddress = helper.ethAddress.fromCollectionId(0);60 const contract = await helper.ethNativeContract.collection(collectionAddress, 'ft', owner);6162 const name = await contract.methods.name().call({from: owner});63 expect(name).to.be.eq('opal');64 });6566 itEth('symbol()', async ({helper}) => {67 const owner = await helper.eth.createAccountWithBalance(donor);68 const collectionAddress = helper.ethAddress.fromCollectionId(0);69 const contract = await helper.ethNativeContract.collection(collectionAddress, 'ft', owner);7071 const name = await contract.methods.symbol().call({from: owner});72 expect(name).to.be.eq('OPL');73 });7475 itEth('totalSupply()', async ({helper}) => {76 const owner = await helper.eth.createAccountWithBalance(donor);77 const collectionAddress = helper.ethAddress.fromCollectionId(0);78 const contract = await helper.ethNativeContract.collection(collectionAddress, 'ft', owner);7980 const totalSupplyEth = BigInt(await contract.methods.totalSupply().call({from: owner}));81 const totalSupplySub = await helper.balance.getTotalIssuance();82 expect(totalSupplyEth).to.be.eq(totalSupplySub);83 });8485 itEth('transfer()', async ({helper}) => {86 const owner = await helper.eth.createAccountWithBalance(donor);87 const receiver = await helper.eth.createAccountWithBalance(donor);88 const collectionAddress = helper.ethAddress.fromCollectionId(0);89 const contract = await helper.ethNativeContract.collection(collectionAddress, 'ft', owner);9091 const balanceOwnerBefore = await helper.balance.getEthereum(owner);92 const balanceReceiverBefore = await helper.balance.getEthereum(receiver);9394 await contract.methods.transfer(receiver, 50).send({from: owner});9596 const balanceOwnerAfter = await helper.balance.getEthereum(owner);97 const balanceReceiverAfter = await helper.balance.getEthereum(receiver);9899 expect(balanceOwnerBefore - 50n > balanceOwnerAfter).to.be.true;100 expect(balanceReceiverBefore === balanceReceiverAfter - 50n).to.be.true;101 });102103 itEth('transferFrom()', async ({helper}) => {104 const owner = await helper.eth.createAccountWithBalance(donor);105 const receiver = await helper.eth.createAccountWithBalance(donor);106 const collectionAddress = helper.ethAddress.fromCollectionId(0);107 const contract = await helper.ethNativeContract.collection(collectionAddress, 'ft', owner);108109 const balanceOwnerBefore = await helper.balance.getEthereum(owner);110 const balanceReceiverBefore = await helper.balance.getEthereum(receiver);111112 await contract.methods.transferFrom(owner, receiver, 50).send({from: owner});113114 const balanceOwnerAfter = await helper.balance.getEthereum(owner);115 const balanceReceiverAfter = await helper.balance.getEthereum(receiver);116117 expect(balanceOwnerBefore - 50n > balanceOwnerAfter).to.be.true;118 expect(balanceReceiverBefore === balanceReceiverAfter - 50n).to.be.true;119120 await expect(contract.methods.transferFrom(receiver, receiver, 50).call({from: owner})).to.be.rejectedWith('no permission');121 });43});122});123124describe('NativeFungible: ERC20UniqueExtensions calls', () => {125 let donor: IKeyringPair;126127 before(async function() {128 await usingEthPlaygrounds(async (helper, privateKey) => {129 donor = await privateKey({url: import.meta.url});130 // [alice] = await helper.arrange.createAccounts([30n], donor);131 });132 });133134 itEth('transferCross()', async ({helper}) => {135 const owner = await helper.eth.createAccountWithBalance(donor);136 const receiver = await helper.ethCrossAccount.createAccountWithBalance(donor);137 const collectionAddress = helper.ethAddress.fromCollectionId(0);138 const contract = await helper.ethNativeContract.collection(collectionAddress, 'ft', owner);139140 const balanceOwnerBefore = await helper.balance.getEthereum(owner);141 const balanceReceiverBefore = await helper.balance.getEthereum(receiver.eth);142143 await contract.methods.transferCross(receiver, 50).send({from: owner});144145 const balanceOwnerAfter = await helper.balance.getEthereum(owner);146 const balanceReceiverAfter = await helper.balance.getEthereum(receiver.eth);147148 expect(balanceOwnerBefore - 50n > balanceOwnerAfter).to.be.true;149 expect(balanceReceiverBefore === balanceReceiverAfter - 50n).to.be.true;150 });151152 itEth('transferFromCross()', async ({helper}) => {153 const owner = await helper.ethCrossAccount.createAccountWithBalance(donor);154 const receiver = await helper.ethCrossAccount.createAccountWithBalance(donor);155 const collectionAddress = helper.ethAddress.fromCollectionId(0);156 const contract = await helper.ethNativeContract.collection(collectionAddress, 'ft', owner.eth);157158 const balanceOwnerBefore = await helper.balance.getEthereum(owner.eth);159 const balanceReceiverBefore = await helper.balance.getEthereum(receiver.eth);160161 await contract.methods.transferFromCross(owner, receiver, 50).send({from: owner.eth});162163 const balanceOwnerAfter = await helper.balance.getEthereum(owner.eth);164 const balanceReceiverAfter = await helper.balance.getEthereum(receiver.eth);165166 expect(balanceOwnerBefore - 50n > balanceOwnerAfter).to.be.true;167 expect(balanceReceiverBefore === balanceReceiverAfter - 50n).to.be.true;168169 await expect(contract.methods.transferFromCross(receiver, receiver, 50).call({from: owner.eth})).to.be.rejectedWith('no permission');170 });171});tests/src/eth/util/playgrounds/unique.dev.tsdiffbeforeafterboth142142143 async collection(address: string, mode: TCollectionMode, caller?: string, mergeDeprecated = false) {143 async collection(address: string, mode: TCollectionMode, caller?: string, mergeDeprecated = false) {144 let abi;144 let abi;145 if (address === '0x17C4e6453cC49aaAAEaCA894E6d9683e00000000' && mode === 'ft') {145 if (address === '0x17C4e6453cC49aaAAEaCA894E6d9683e00000000') {146 abi = nativeFungibleAbi;146 abi = nativeFungibleAbi;147 } else {147 } else {148 abi ={148 abi ={tests/src/util/playgrounds/unique.tsdiffbeforeafterboth2400 return {free: accountInfo.free.toBigInt(), frozen: accountInfo.frozen.toBigInt(), reserved: accountInfo.reserved.toBigInt()};2400 return {free: accountInfo.free.toBigInt(), frozen: accountInfo.frozen.toBigInt(), reserved: accountInfo.reserved.toBigInt()};2401 }2401 }24022403 /**2404 * Get total issuance2405 * @returns2406 */2407 async getTotalIssuance(): Promise<bigint> {2408 const total = (await this.helper.callRpc('api.query.balances.totalIssuance', []));2409 return total.toBigInt();2410 }240224112403 async getLocked(address: TSubstrateAccount): Promise<[{ id: string, amount: bigint, reason: string }]> {2412 async getLocked(address: TSubstrateAccount): Promise<[{id: string, amount: bigint, reason: string}]> {2404 const locks = (await this.helper.callRpc('api.query.balances.locks', [address])).toHuman();2413 const locks = (await this.helper.callRpc('api.query.balances.locks', [address])).toHuman();2487 return this.subBalanceGroup.getSubstrateFull(address);2496 return this.subBalanceGroup.getSubstrateFull(address);2488 }2497 }24982499 /**2500 * Get total issuance2501 * @returns2502 */2503 getTotalIssuance(): Promise<bigint> {2504 return this.subBalanceGroup.getTotalIssuance();2505 }248925062490 /**2507 /**2491 * Get locked balances2508 * Get locked balances