From 5a21159fba9071a86afa210d537c5562ebfb84e0 Mon Sep 17 00:00:00 2001 From: lovesh Date: Wed, 28 Oct 2020 05:03:21 +0530 Subject: [PATCH] Fix migrateRecipAsList for repeated address Signed-off-by: lovesh --- package.json | 2 +- scripts/helpers.js | 2 +- src/modules/migration.js | 19 +++++++++++++++++-- tests/poa/token_migration.test.js | 28 +++++++++++++++++++++------- 4 files changed, 40 insertions(+), 11 deletions(-) diff --git a/package.json b/package.json index 1ecb94cfc..84da6b656 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@docknetwork/sdk", - "version": "0.3.6", + "version": "0.3.7", "main": "index.js", "license": "MIT", "repository": { diff --git a/scripts/helpers.js b/scripts/helpers.js index ad619663c..ddd92728d 100644 --- a/scripts/helpers.js +++ b/scripts/helpers.js @@ -49,7 +49,7 @@ export async function validatorChange(dock, argv, func, senderAccountUri) { * @param {*} txs * @param {*} senderAddress */ -export async function sendBatch(dock, txs, senderAddress, waitForFinalization = true) { +export async function sendBatch(dock, txs, senderAddress, waitForFinalization = false) { const txBatch = dock.api.tx.utility.batch(txs); console.log(`Batch size is ${txBatch.encodedLength}`); console.info(`Payment info of batch is ${(await txBatch.paymentInfo(senderAddress))}`); diff --git a/src/modules/migration.js b/src/modules/migration.js index ac7c1de29..1c70e7181 100644 --- a/src/modules/migration.js +++ b/src/modules/migration.js @@ -1,4 +1,5 @@ import { BTreeMap } from '@polkadot/types'; +import { bnToBn } from '@polkadot/util'; const MaxAllowedMigrations = 65535; @@ -31,12 +32,26 @@ class TokenMigration { return this.api.tx.migrationModule.migrate(recipients); } - // Accepts recipients as an array of pairs, each pair is (address, amount) + // Accepts recipients as an array of pairs, each pair is (address, amount). Amount can either be a safe JS integer + // or a string which will be expected in decimal format. If an address is repeated, its intended amounts are added. migrateRecipAsList(recipients) { // @ts-ignore const recipMap = new BTreeMap(); recipients.sort().forEach(([address, amount]) => { - recipMap.set(address, amount); + const existingVal = recipMap.get(address); + let value = amount; + if (existingVal !== undefined) { + // The list in argument repeated addresses. Convert both existing and new values to big number and add. + // An alternative could be trying to parse both as either safe integer (`Number.isSafeInteger`) and then checking + // if no overflow happens on add and if it does then try to convert to BN + const newVal = bnToBn(amount); + // @ts-ignore + const oldVal = bnToBn(existingVal); + const sum = newVal.add(oldVal); + // Convert to string decimal representation. + value = sum.toString(); + } + recipMap.set(address, value); }); return this.api.tx.migrationModule.migrate(recipMap); } diff --git a/tests/poa/token_migration.test.js b/tests/poa/token_migration.test.js index d31aa7c00..2711c99fe 100644 --- a/tests/poa/token_migration.test.js +++ b/tests/poa/token_migration.test.js @@ -41,11 +41,11 @@ describe('Token migration', () => { test('Add migrator', async () => { let migrators = await sudoHandle.migrationModule.getMigrators(); - expect(migrators.length).toBe(0); - const txn = sudoHandle.migrationModule.addMigrator(charlie, 6, true); + const initialMigratorCount = migrators.length; + const txn = sudoHandle.migrationModule.addMigrator(charlie, 10, true); await sudoHandle.signAndSend(txn, false); migrators = await queryHandle.migrationModule.getMigrators(); - expect(migrators.length).toBe(1); + expect(migrators.length).toBe(initialMigratorCount + 1); }, 20000); test('Migrate', async () => { @@ -58,11 +58,11 @@ describe('Token migration', () => { // @ts-ignore const recip1 = new BTreeMap(); // @ts-ignore - recip1.set(ferdie, 300); + recip1.set(ferdie, '300'); // @ts-ignore - recip1.set(dave, 200); + recip1.set(dave, '200'); // @ts-ignore - recip1.set(eve, 100); + recip1.set(eve, '100'); const txn = charlieHandle.migrationModule.migrate(recip1); await charlieHandle.signAndSend(txn, false); @@ -77,7 +77,7 @@ describe('Token migration', () => { expect(eveBal2).toBe(eveBal1 + 100); expect(ferdieBal2).toBe(ferdieBal1 + 300); - const recipList = [[dave, 100], [eve, 110], [ferdie, 120]]; + const recipList = [[dave, '100'], [eve, '110'], [ferdie, '120']]; const txn1 = charlieHandle.migrationModule.migrateRecipAsList(recipList); await charlieHandle.signAndSend(txn1, false); @@ -90,6 +90,20 @@ describe('Token migration', () => { expect(daveBal3).toBe(daveBal2 + 100); expect(eveBal3).toBe(eveBal2 + 110); expect(ferdieBal3).toBe(ferdieBal2 + 120); + + const recipListWithRepeatedAddreses = [[dave, '100'], [eve, 110], [dave, '400'], [dave, '500'], [dave, 1000], [ferdie, '120'], [ferdie, 300]]; + const txn2 = charlieHandle.migrationModule.migrateRecipAsList(recipListWithRepeatedAddreses); + await charlieHandle.signAndSend(txn2, false); + + const charlieBal4 = parseInt(await getFreeBalance(queryHandle, charlie)); + const daveBal4 = parseInt(await getFreeBalance(queryHandle, dave)); + const eveBal4 = parseInt(await getFreeBalance(queryHandle, eve)); + const ferdieBal4 = parseInt(await getFreeBalance(queryHandle, ferdie)); + + expect(charlieBal3).toBe(charlieBal4 + 100 + 110 + 400 + 500 + 1000 + 120 + 300); + expect(daveBal4).toBe(daveBal3 + 2000); + expect(eveBal4).toBe(eveBal3 + 110); + expect(ferdieBal4).toBe(ferdieBal3 + 420); }, 40000); afterAll(async (done) => {