From 42ce186df417e63bc3d0e087888431787169a130 Mon Sep 17 00:00:00 2001 From: Yaroslav Bolyukin Date: Mon, 08 Aug 2022 08:06:30 +0000 Subject: [PATCH] Merge pull request #468 from UniqueNetwork/fix/fungible-pallet-wrong-amount-in-item-created-event --- --- a/Cargo.lock +++ b/Cargo.lock @@ -5944,7 +5944,7 @@ [[package]] name = "pallet-fungible" -version = "0.1.1" +version = "0.1.2" dependencies = [ "ethereum", "evm-coder", --- a/pallets/fungible/CHANGELOG.md +++ b/pallets/fungible/CHANGELOG.md @@ -2,6 +2,12 @@ All notable changes to this project will be documented in this file. +## [0.1.2] - 2022-08-04 + +### Fixed + + - Issue with ItemCreated event containing total supply of tokens instead minted amount + ## [0.1.1] - 2022-07-14 ### Added --- a/pallets/fungible/Cargo.toml +++ b/pallets/fungible/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-fungible" -version = "0.1.1" +version = "0.1.2" license = "GPLv3" edition = "2021" --- a/pallets/fungible/src/lib.rs +++ b/pallets/fungible/src/lib.rs @@ -393,14 +393,7 @@ }) .ok_or(ArithmeticError::Overflow)?; - let mut balances = data; - for (k, v) in balances.iter_mut() { - *v = >::get((collection.id, &k)) - .checked_add(*v) - .ok_or(ArithmeticError::Overflow)?; - } - - for (to, _) in balances.iter() { + for (to, _) in data.iter() { >::check_nesting( sender.clone(), to, @@ -410,11 +403,21 @@ )?; } + let updated_balances = data + .into_iter() + .map(|(user, amount)| { + let updated_balance = >::get((collection.id, &user)) + .checked_add(amount) + .ok_or(ArithmeticError::Overflow)?; + Ok((user, amount, updated_balance)) + }) + .collect::, DispatchError>>()?; + // ========= >::insert(collection.id, total_supply); - for (user, amount) in balances { - >::insert((collection.id, &user), amount); + for (user, amount, updated_balance) in updated_balances { + >::insert((collection.id, &user), updated_balance); >::nest_if_sent_to_token_unchecked( &user, collection.id, --- a/tests/src/createItem.test.ts +++ b/tests/src/createItem.test.ts @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Unique Network. If not, see . -import {default as usingApi} from './substrate/substrate-api'; +import {default as usingApi, executeTransaction} from './substrate/substrate-api'; import chai from 'chai'; import {IKeyringPair} from '@polkadot/types/types'; import { @@ -26,6 +26,9 @@ createItemWithPropsExpectFailure, createCollection, transferExpectSuccess, + itApi, + normalizeAccountId, + getCreateItemResult, } from './util/helpers'; const expect = chai.expect; @@ -50,6 +53,32 @@ const newCollectionID = await createCollectionExpectSuccess({mode: {type: createMode, decimalPoints: 0}}); await createItemExpectSuccess(alice, newCollectionID, createMode); }); + itApi('Check events on create new item in Fungible collection', async ({api}) => { + const createMode = 'Fungible'; + + const newCollectionID = (await createCollection(api, alice, {mode: {type: createMode, decimalPoints: 0}})).collectionId; + + const to = normalizeAccountId(alice); + { + const createData = {fungible: {value: 100}}; + const tx = api.tx.unique.createItem(newCollectionID, to, createData as any); + const events = await executeTransaction(api, alice, tx); + const result = getCreateItemResult(events); + expect(result.amount).to.be.equal(100); + expect(result.collectionId).to.be.equal(newCollectionID); + expect(result.recipient).to.be.deep.equal(to); + } + { + const createData = {fungible: {value: 50}}; + const tx = api.tx.unique.createItem(newCollectionID, to, createData as any); + const events = await executeTransaction(api, alice, tx); + const result = getCreateItemResult(events); + expect(result.amount).to.be.equal(50); + expect(result.collectionId).to.be.equal(newCollectionID); + expect(result.recipient).to.be.deep.equal(to); + } + + }); it('Create new item in ReFungible collection', async () => { const createMode = 'ReFungible'; const newCollectionID = await createCollectionExpectSuccess({mode: {type: createMode}}); --- a/tests/src/util/helpers.ts +++ b/tests/src/util/helpers.ts @@ -248,22 +248,23 @@ } export function getCreateItemResult(events: EventRecord[]): CreateItemResult { - const genericResult = getGenericResult<[number, number, CrossAccountId?]>(events, 'common', 'ItemCreated', (data) => [ - parseInt(data[0].toString(), 10), - parseInt(data[1].toString(), 10), - normalizeAccountId(data[2].toJSON() as any), - ]); - - if (genericResult.data == null) genericResult.data = [0, 0]; - - const result: CreateItemResult = { - success: genericResult.success, - collectionId: genericResult.data[0], - itemId: genericResult.data[1], - recipient: genericResult.data![2], - }; + const genericResult = getGenericResult(events, 'common', 'ItemCreated', (data) => data.map(function(value) { return value.toJSON(); })); - return result; + if (genericResult.data == null) + return { + success: genericResult.success, + collectionId: 0, + itemId: 0, + amount: 0, + }; + else + return { + success: genericResult.success, + collectionId: genericResult.data[0] as number, + itemId: genericResult.data[1] as number, + recipient: normalizeAccountId(genericResult.data![2] as any), + amount: genericResult.data[3] as number, + }; } export function getDestroyItemsResult(events: EventRecord[]): DestroyItemResult[] { @@ -1699,3 +1700,17 @@ return result.success; } + +export async function itApi(name: string, cb: (apis: { api: ApiPromise, privateKeyWrapper: (account: string) => IKeyringPair }) => any, opts: { only?: boolean, skip?: boolean } = {}) { + let i: any = it; + if (opts.only) i = i.only; + else if (opts.skip) i = i.skip; + i(name, async () => { + await usingApi(async (api, privateKeyWrapper) => { + await cb({api, privateKeyWrapper}); + }); + }); +} + +itApi.only = (name: string, cb: (apis: { api: ApiPromise, privateKeyWrapper: (account: string) => IKeyringPair }) => any) => itApi(name, cb, {only: true}); +itApi.skip = (name: string, cb: (apis: { api: ApiPromise, privateKeyWrapper: (account: string) => IKeyringPair }) => any) => itApi(name, cb, {skip: true}); -- gitstuff