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

difftreelog

Merge pull request #615 from UniqueNetwork/feature/playground-helpers

ut-akuznetsov2022-09-29parents: #6b0c031 #62959b2.patch.diff
in: master
Add calculateFee method to playgrounds

3 files changed

modifiedtests/src/eth/payable.test.tsdiffbeforeafterboth
before · tests/src/eth/payable.test.ts
1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617import {IKeyringPair} from '@polkadot/types/types';1819import {itEth, expect, usingEthPlaygrounds} from './util/playgrounds';2021describe('EVM payable contracts', () => {22  let donor: IKeyringPair;2324  before(async function() {25    await usingEthPlaygrounds(async (_, privateKey) => {26      donor = privateKey('//Alice');27    });28  });2930  itEth('Evm contract can receive wei from eth account', async ({helper}) => {31    const deployer = await helper.eth.createAccountWithBalance(donor);32    const contract = await helper.eth.deployCollectorContract(deployer);3334    const web3 = helper.getWeb3();3536    await web3.eth.sendTransaction({from: deployer, to: contract.options.address, value: '10000', gas: helper.eth.DEFAULT_GAS});3738    expect(await contract.methods.getCollected().call()).to.be.equal('10000');39  });4041  itEth('Evm contract can receive wei from substrate account', async ({helper}) => {42    const deployer = await helper.eth.createAccountWithBalance(donor);43    const contract = await helper.eth.deployCollectorContract(deployer);44    const [alice] = await helper.arrange.createAccounts([10n], donor);4546    const weiCount = '10000';4748    // Transaction fee/value will be payed from subToEth(sender) evm balance,49    // which is backed by evmToAddress(subToEth(sender)) substrate balance50    await helper.eth.transferBalanceFromSubstrate(alice, helper.address.substrateToEth(alice.address), 5n);515253    await helper.eth.callEVM(alice, contract.options.address, contract.methods.giveMoney().encodeABI(), weiCount);5455    expect(await contract.methods.getCollected().call()).to.be.equal(weiCount);56  });5758  // We can't handle sending balance to backing storage of evm balance, because evmToAddress operation is irreversible59  itEth('Wei sent directly to backing storage of evm contract balance is unaccounted', async({helper}) => {60    const deployer = await helper.eth.createAccountWithBalance(donor);61    const contract = await helper.eth.deployCollectorContract(deployer);62    const [alice] = await helper.arrange.createAccounts([10n], donor);6364    const weiCount = 10_000n;6566    await helper.eth.transferBalanceFromSubstrate(alice, contract.options.address, weiCount, false);6768    expect(await contract.methods.getUnaccounted().call()).to.be.equal(weiCount.toString());69  });7071  itEth('Balance can be retrieved from evm contract', async({helper, privateKey}) => {72    const FEE_BALANCE = 10n * helper.balance.getOneTokenNominal();73    const CONTRACT_BALANCE = 1n * helper.balance.getOneTokenNominal();7475    const deployer = await helper.eth.createAccountWithBalance(donor);76    const contract = await helper.eth.deployCollectorContract(deployer);77    const [alice] = await helper.arrange.createAccounts([20n], donor);7879    const web3 = helper.getWeb3();8081    await web3.eth.sendTransaction({from: deployer, to: contract.options.address, value: CONTRACT_BALANCE.toString(), gas: helper.eth.DEFAULT_GAS});8283    const receiver = privateKey(`//Receiver${Date.now()}`);8485    // First receive balance on eth balance of bob86    {87      const ethReceiver = helper.address.substrateToEth(receiver.address);88      expect(await web3.eth.getBalance(ethReceiver)).to.be.equal('0');89      await contract.methods.withdraw(ethReceiver).send({from: deployer});90      expect(await web3.eth.getBalance(ethReceiver)).to.be.equal(CONTRACT_BALANCE.toString());91    }9293    // Some balance is required to pay fee for evm.withdraw call94    await helper.balance.transferToSubstrate(alice, receiver.address, FEE_BALANCE);95    // await transferBalanceExpectSuccess(api, alice, receiver.address, FEE_BALANCE.toString());9697    // Withdraw balance from eth to substrate98    {99      const initialReceiverBalance = await helper.balance.getSubstrate(receiver.address);100      await helper.executeExtrinsic(receiver, 'api.tx.evm.withdraw', [helper.address.substrateToEth(receiver.address), CONTRACT_BALANCE.toString()], true);101      const finalReceiverBalance = await helper.balance.getSubstrate(receiver.address);102103      expect(finalReceiverBalance > initialReceiverBalance).to.be.true;104    }105  });106});
after · tests/src/eth/payable.test.ts
1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617import {IKeyringPair} from '@polkadot/types/types';1819import {itEth, expect, usingEthPlaygrounds} from './util/playgrounds';2021describe('EVM payable contracts', () => {22  let donor: IKeyringPair;2324  before(async function() {25    await usingEthPlaygrounds(async (_, privateKey) => {26      donor = privateKey('//Alice');27    });28  });2930  itEth('Evm contract can receive wei from eth account', async ({helper}) => {31    const deployer = await helper.eth.createAccountWithBalance(donor);32    const contract = await helper.eth.deployCollectorContract(deployer);3334    const web3 = helper.getWeb3();3536    await web3.eth.sendTransaction({from: deployer, to: contract.options.address, value: '10000', gas: helper.eth.DEFAULT_GAS});3738    expect(await contract.methods.getCollected().call()).to.be.equal('10000');39  });4041  itEth('Evm contract can receive wei from substrate account', async ({helper}) => {42    const deployer = await helper.eth.createAccountWithBalance(donor);43    const contract = await helper.eth.deployCollectorContract(deployer);44    const [alice] = await helper.arrange.createAccounts([10n], donor);4546    const weiCount = '10000';4748    // Transaction fee/value will be payed from subToEth(sender) evm balance,49    // which is backed by evmToAddress(subToEth(sender)) substrate balance50    await helper.eth.transferBalanceFromSubstrate(alice, helper.address.substrateToEth(alice.address), 5n);515253    await helper.eth.sendEVM(alice, contract.options.address, contract.methods.giveMoney().encodeABI(), weiCount);5455    expect(await contract.methods.getCollected().call()).to.be.equal(weiCount);56  });5758  // We can't handle sending balance to backing storage of evm balance, because evmToAddress operation is irreversible59  itEth('Wei sent directly to backing storage of evm contract balance is unaccounted', async({helper}) => {60    const deployer = await helper.eth.createAccountWithBalance(donor);61    const contract = await helper.eth.deployCollectorContract(deployer);62    const [alice] = await helper.arrange.createAccounts([10n], donor);6364    const weiCount = 10_000n;6566    await helper.eth.transferBalanceFromSubstrate(alice, contract.options.address, weiCount, false);6768    expect(await contract.methods.getUnaccounted().call()).to.be.equal(weiCount.toString());69  });7071  itEth('Balance can be retrieved from evm contract', async({helper, privateKey}) => {72    const FEE_BALANCE = 10n * helper.balance.getOneTokenNominal();73    const CONTRACT_BALANCE = 1n * helper.balance.getOneTokenNominal();7475    const deployer = await helper.eth.createAccountWithBalance(donor);76    const contract = await helper.eth.deployCollectorContract(deployer);77    const [alice] = await helper.arrange.createAccounts([20n], donor);7879    const web3 = helper.getWeb3();8081    await web3.eth.sendTransaction({from: deployer, to: contract.options.address, value: CONTRACT_BALANCE.toString(), gas: helper.eth.DEFAULT_GAS});8283    const receiver = privateKey(`//Receiver${Date.now()}`);8485    // First receive balance on eth balance of bob86    {87      const ethReceiver = helper.address.substrateToEth(receiver.address);88      expect(await web3.eth.getBalance(ethReceiver)).to.be.equal('0');89      await contract.methods.withdraw(ethReceiver).send({from: deployer});90      expect(await web3.eth.getBalance(ethReceiver)).to.be.equal(CONTRACT_BALANCE.toString());91    }9293    // Some balance is required to pay fee for evm.withdraw call94    await helper.balance.transferToSubstrate(alice, receiver.address, FEE_BALANCE);95    // await transferBalanceExpectSuccess(api, alice, receiver.address, FEE_BALANCE.toString());9697    // Withdraw balance from eth to substrate98    {99      const initialReceiverBalance = await helper.balance.getSubstrate(receiver.address);100      await helper.executeExtrinsic(receiver, 'api.tx.evm.withdraw', [helper.address.substrateToEth(receiver.address), CONTRACT_BALANCE.toString()], true);101      const finalReceiverBalance = await helper.balance.getSubstrate(receiver.address);102103      expect(finalReceiverBalance > initialReceiverBalance).to.be.true;104    }105  });106});
modifiedtests/src/eth/util/playgrounds/unique.dev.tsdiffbeforeafterboth
--- a/tests/src/eth/util/playgrounds/unique.dev.ts
+++ b/tests/src/eth/util/playgrounds/unique.dev.ts
@@ -27,6 +27,7 @@
 import refungibleAbi from '../../reFungibleAbi.json';
 import refungibleTokenAbi from '../../reFungibleTokenAbi.json';
 import contractHelpersAbi from './../contractHelpersAbi.json';
+import {TEthereumAccount} from '../../../util/playgrounds/types';
 
 class EthGroupBase {
   helper: EthUniqueHelper;
@@ -43,13 +44,13 @@
       return {error: `File not found: ${path}`};
     };
   
-    const knownImports = {} as any;
+    const knownImports = {} as {[key: string]: string};
     for(const imp of imports) {
       knownImports[imp.solPath] = (await readFile(imp.fsPath)).toString();
     }
   
     return function(path: string) {
-      if(knownImports.hasOwnPropertyDescriptor(path)) return {contents: knownImports[path]};
+      if(path in knownImports) return {contents: knownImports[path]};
       return {error: `File not found: ${path}`};
     };
   }
@@ -148,7 +149,7 @@
     return await this.helper.balance.transferToSubstrate(donor, evmToAddress(recepient), amount * (inTokens ? this.helper.balance.getOneTokenNominal() : 1n));
   }
 
-  async callEVM(signer: IKeyringPair, contractAddress: string, abi: any, value: string, gasLimit?: number) {
+  async sendEVM(signer: IKeyringPair, contractAddress: string, abi: string, value: string, gasLimit?: number) {
     if(!gasLimit) gasLimit = this.DEFAULT_GAS;
     const web3 = this.helper.getWeb3();
     const gasPrice = await web3.eth.getGasPrice();
@@ -159,6 +160,10 @@
       true,
     );
   }
+  
+  async callEVM(signer: TEthereumAccount, contractAddress: string, abi: string) {
+    return await this.helper.callRpc('api.rpc.eth.call', [{from: signer, to: contractAddress, data: abi}]);
+  }
 
   async createNonfungibleCollection(signer: string, name: string, description: string, tokenPrefix: string): Promise<{collectionId: number, collectionAddress: string}> {
     const collectionHelper = this.helper.ethNativeContract.collectionHelpers(signer);
modifiedtests/src/util/playgrounds/unique.dev.tsdiffbeforeafterboth
--- a/tests/src/util/playgrounds/unique.dev.ts
+++ b/tests/src/util/playgrounds/unique.dev.ts
@@ -6,6 +6,7 @@
 import {ApiPromise, WsProvider} from '@polkadot/api';
 import * as defs from '../../interfaces/definitions';
 import {IKeyringPair} from '@polkadot/types/types';
+import {ICrossAccountId} from './types';
 
 
 export class SilentLogger {
@@ -230,6 +231,17 @@
     const block2date = await findCreationDate(block2);
     if(block2date! - block1date! < 9000) return true;
   };
+  
+  async calculcateFee(payer: ICrossAccountId, promise: () => Promise<any>): Promise<bigint> {
+    const address = payer.Substrate ? payer.Substrate : await this.helper.address.ethToSubstrate(payer.Ethereum!);
+    let balance = await this.helper.balance.getSubstrate(address); 
+    
+    await promise();
+    
+    balance -= await this.helper.balance.getSubstrate(address);
+    
+    return balance;
+  }
 }
 
 class WaitGroup {