git.delta.rocks / unique-network / refs/commits / 42ce186df417

difftreelog

Merge pull request #468 from UniqueNetwork/fix/fungible-pallet-wrong-amount-in-item-created-event

Yaroslav Bolyukin2022-08-08parents: #50fb43d #26386c5.patch.diff
in: master

6 files changed

modifiedCargo.lockdiffbeforeafterboth
--- 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",
modifiedpallets/fungible/CHANGELOG.mddiffbeforeafterboth
--- 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
modifiedpallets/fungible/Cargo.tomldiffbeforeafterboth
--- 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"
 
modifiedpallets/fungible/src/lib.rsdiffbeforeafterboth
--- 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 = <Balance<T>>::get((collection.id, &k))
-				.checked_add(*v)
-				.ok_or(ArithmeticError::Overflow)?;
-		}
-
-		for (to, _) in balances.iter() {
+		for (to, _) in data.iter() {
 			<PalletStructure<T>>::check_nesting(
 				sender.clone(),
 				to,
@@ -410,11 +403,21 @@
 			)?;
 		}
 
+		let updated_balances = data
+			.into_iter()
+			.map(|(user, amount)| {
+				let updated_balance = <Balance<T>>::get((collection.id, &user))
+					.checked_add(amount)
+					.ok_or(ArithmeticError::Overflow)?;
+				Ok((user, amount, updated_balance))
+			})
+			.collect::<Result<Vec<_>, DispatchError>>()?;
+
 		// =========
 
 		<TotalSupply<T>>::insert(collection.id, total_supply);
-		for (user, amount) in balances {
-			<Balance<T>>::insert((collection.id, &user), amount);
+		for (user, amount, updated_balance) in updated_balances {
+			<Balance<T>>::insert((collection.id, &user), updated_balance);
 			<PalletStructure<T>>::nest_if_sent_to_token_unchecked(
 				&user,
 				collection.id,
modifiedtests/src/createItem.test.tsdiffbeforeafterboth
14// You should have received a copy of the GNU General Public License14// You should have received a copy of the GNU General Public License
15// 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/>.
1616
17import {default as usingApi} from './substrate/substrate-api';17import {default as usingApi, executeTransaction} from './substrate/substrate-api';
18import chai from 'chai';18import chai from 'chai';
19import {IKeyringPair} from '@polkadot/types/types';19import {IKeyringPair} from '@polkadot/types/types';
20import {20import {
26 createItemWithPropsExpectFailure,26 createItemWithPropsExpectFailure,
27 createCollection,27 createCollection,
28 transferExpectSuccess,28 transferExpectSuccess,
29 itApi,
30 normalizeAccountId,
31 getCreateItemResult,
29} from './util/helpers';32} from './util/helpers';
3033
31const expect = chai.expect;34const expect = chai.expect;
50 const newCollectionID = await createCollectionExpectSuccess({mode: {type: createMode, decimalPoints: 0}});53 const newCollectionID = await createCollectionExpectSuccess({mode: {type: createMode, decimalPoints: 0}});
51 await createItemExpectSuccess(alice, newCollectionID, createMode);54 await createItemExpectSuccess(alice, newCollectionID, createMode);
52 });55 });
56 itApi('Check events on create new item in Fungible collection', async ({api}) => {
57 const createMode = 'Fungible';
58
59 const newCollectionID = (await createCollection(api, alice, {mode: {type: createMode, decimalPoints: 0}})).collectionId;
60
61 const to = normalizeAccountId(alice);
62 {
63 const createData = {fungible: {value: 100}};
64 const tx = api.tx.unique.createItem(newCollectionID, to, createData as any);
65 const events = await executeTransaction(api, alice, tx);
66 const result = getCreateItemResult(events);
67 expect(result.amount).to.be.equal(100);
68 expect(result.collectionId).to.be.equal(newCollectionID);
69 expect(result.recipient).to.be.deep.equal(to);
70 }
71 {
72 const createData = {fungible: {value: 50}};
73 const tx = api.tx.unique.createItem(newCollectionID, to, createData as any);
74 const events = await executeTransaction(api, alice, tx);
75 const result = getCreateItemResult(events);
76 expect(result.amount).to.be.equal(50);
77 expect(result.collectionId).to.be.equal(newCollectionID);
78 expect(result.recipient).to.be.deep.equal(to);
79 }
80
81 });
53 it('Create new item in ReFungible collection', async () => {82 it('Create new item in ReFungible collection', async () => {
54 const createMode = 'ReFungible';83 const createMode = 'ReFungible';
55 const newCollectionID = await createCollectionExpectSuccess({mode: {type: createMode}});84 const newCollectionID = await createCollectionExpectSuccess({mode: {type: createMode}});
modifiedtests/src/util/helpers.tsdiffbeforeafterboth
--- 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});