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

difftreelog

source

tests/src/benchmarks/mintFee/mintFee.ts10.2 KiBsourcehistory
1import {EthUniqueHelper, usingEthPlaygrounds} from '../../eth/util';2import {readFile} from 'fs/promises';3import {4  ICrossAccountId,5} from '../../util/playgrounds/types';6import {IKeyringPair} from '@polkadot/types/types';7import {UniqueNFTCollection} from '../../util/playgrounds/unique';8import {Contract} from 'web3-eth-contract';9import {createObjectCsvWriter} from 'csv-writer';10import {CONTRACT_IMPORT, convertToTokens, createCollectionForBenchmarks, PERMISSIONS, PROPERTIES} from './common';11121314interface IBenchmarkResultForProp {15	propertiesNumber: number;16	substrateFee: number;17	ethFee: number;18	ethBulkFee: number;19  ethMintCrossFee: number;20	evmProxyContractFee: number;21	evmProxyContractBulkFee: number;22}2324const main = async () => {25  const benchmarks = [26    'substrateFee',27    'ethFee',28    'ethBulkFee',29    'ethMintCrossFee',30    'evmProxyContractFee',31    'evmProxyContractBulkFee',32  ];33  const headers = [34    'propertiesNumber',35    ...benchmarks,36  ];373839  const csvWriter = createObjectCsvWriter({40    path: 'properties.csv',41    header: headers,42  });4344  await usingEthPlaygrounds(async (helper, privateKey) => {45    const CONTRACT_SOURCE = (46      await readFile(`${__dirname}/proxyContract.sol`)47    ).toString();4849    const donor = await privateKey('//Alice'); // Seed from account with balance on this network50    const ethSigner = await helper.eth.createAccountWithBalance(donor, 100n);5152    const contract = await helper.ethContract.deployByCode(53      ethSigner,54      'ProxyMint',55      CONTRACT_SOURCE,56      CONTRACT_IMPORT,57    );5859    const fees = await benchMintFee(helper, privateKey, contract);60    console.log('Minting without properties');61    console.table(fees);6263    const result: IBenchmarkResultForProp[] = [];64    const csvResult: IBenchmarkResultForProp[] = [];6566    for (let i = 1; i <= 20; i++) {67      const benchResult = await benchMintWithProperties(helper, privateKey, contract, {68        propertiesNumber: i,69      }) as any;7071      csvResult.push(benchResult);7273      const minFee = Math.min(...(benchmarks.map(x => benchResult[x])));74      for(const key of benchmarks) {75        const keyPercent = Math.round((benchResult[key] / minFee) * 100);76        benchResult[key] = `${benchResult[key]} (${keyPercent}%)`;77      }7879      result.push(benchResult);80    }8182    await csvWriter.writeRecords(csvResult);8384    console.log('Minting with properties');85    console.table(result, headers);86  });87};8889main()90  .then(() => process.exit(0))91  .catch((e) => {92    console.log(e);93    process.exit(1);94  });95969798async function benchMintFee(99  helper: EthUniqueHelper,100  privateKey: (seed: string) => Promise<IKeyringPair>,101  proxyContract: Contract,102): Promise<{103	substrateFee: number;104	ethFee: number;105	evmProxyContractFee: number;106}> {107  const donor = await privateKey('//Alice');108  const substrateReceiver = await privateKey('//Bob');109  const ethSigner = await helper.eth.createAccountWithBalance(donor, 100n);110111  const nominal = helper.balance.getOneTokenNominal();112113  await helper.eth.transferBalanceFromSubstrate(114    donor,115    proxyContract.options.address,116    100n,117  );118119  const collection = (await createCollectionForBenchmarks(120    'nft',121    helper,122    privateKey,123    ethSigner,124    proxyContract.options.address,125    PERMISSIONS,126  )) as UniqueNFTCollection;127128  const substrateFee = await helper.arrange.calculcateFee(129    {Substrate: donor.address},130    () => collection.mintToken(donor, {Substrate: substrateReceiver.address}),131  );132133  const collectionEthAddress = helper.ethAddress.fromCollectionId(collection.collectionId);134  const collectionContract = await helper.ethNativeContract.collection(135    collectionEthAddress,136    'nft',137  );138139  const receiverEthAddress = helper.address.substrateToEth(substrateReceiver.address);140141  const encodedCall = collectionContract.methods142    .mint(receiverEthAddress)143    .encodeABI();144145  const ethFee = await helper.arrange.calculcateFee(146    {Substrate: donor.address},147    async () => {148      await helper.eth.sendEVM(149        donor,150        collectionContract.options.address,151        encodedCall,152        '0',153      );154    },155  );156157  const evmProxyContractFee = await helper.arrange.calculcateFee(158    {Ethereum: ethSigner},159    async () => {160      await proxyContract.methods161        .mintToSubstrate(162          helper.ethAddress.fromCollectionId(collection.collectionId),163          substrateReceiver.addressRaw,164        )165        .send({from: ethSigner});166    },167  );168169  return {170    substrateFee: convertToTokens(substrateFee, nominal),171    ethFee: convertToTokens(ethFee, nominal),172    evmProxyContractFee: convertToTokens(evmProxyContractFee, nominal),173  };174}175176async function benchMintWithProperties(177  helper: EthUniqueHelper,178  privateKey: (seed: string) => Promise<IKeyringPair>,179  proxyContract: Contract,180  setup: { propertiesNumber: number },181): Promise<IBenchmarkResultForProp> {182  const donor = await privateKey('//Alice'); // Seed from account with balance on this network183  const ethSigner = await helper.eth.createAccountWithBalance(donor, 100n);184185  const susbstrateReceiver = await privateKey('//Bob');186  const receiverEthAddress = helper.address.substrateToEth(susbstrateReceiver.address);187188  const nominal = helper.balance.getOneTokenNominal();189190  const substrateFee = await calculateFeeNftMintWithProperties(191    helper,192    privateKey,193    {Substrate: donor.address},194    ethSigner,195    proxyContract.options.address,196    async (collection) => {197      await collection.mintToken(198        donor,199        {Substrate: susbstrateReceiver.address},200        PROPERTIES.slice(0, setup.propertiesNumber).map((p) => {201          return {key: p.key, value: Buffer.from(p.value).toString()};202        }),203      );204    },205  );206207  const ethFee = await calculateFeeNftMintWithProperties(208    helper,209    privateKey,210    {Substrate: donor.address},211    ethSigner,212    proxyContract.options.address,213    async (collection) => {214      const evmContract = await helper.ethNativeContract.collection(215        helper.ethAddress.fromCollectionId(collection.collectionId),216        'nft',217        undefined,218        true,219      );220221      const subTokenId = await evmContract.methods.nextTokenId().call();222223      let encodedCall = evmContract.methods224        .mint(receiverEthAddress)225        .encodeABI();226227      await helper.eth.sendEVM(228        donor,229        evmContract.options.address,230        encodedCall,231        '0',232      );233234      for (const val of PROPERTIES.slice(0, setup.propertiesNumber)) {235        encodedCall = await evmContract.methods236          .setProperty(subTokenId, val.key, Buffer.from(val.value))237          .encodeABI();238239        await helper.eth.sendEVM(240          donor,241          evmContract.options.address,242          encodedCall,243          '0',244        );245      }246    },247  );248249  const ethBulkFee = await calculateFeeNftMintWithProperties(250    helper,251    privateKey,252    {Substrate: donor.address},253    ethSigner,254    proxyContract.options.address,255    async (collection) => {256      const evmContract = await helper.ethNativeContract.collection(257        helper.ethAddress.fromCollectionId(collection.collectionId),258        'nft',259      );260261      const subTokenId = await evmContract.methods.nextTokenId().call();262263      let encodedCall = evmContract.methods264        .mint(receiverEthAddress)265        .encodeABI();266267      await helper.eth.sendEVM(268        donor,269        evmContract.options.address,270        encodedCall,271        '0',272      );273274      encodedCall = await evmContract.methods275        .setProperties(276          subTokenId,277          PROPERTIES.slice(0, setup.propertiesNumber),278        )279        .encodeABI();280281      await helper.eth.sendEVM(282        donor,283        evmContract.options.address,284        encodedCall,285        '0',286      );287    },288  );289290  const ethMintCrossFee = await calculateFeeNftMintWithProperties(291    helper,292    privateKey,293    {Ethereum: ethSigner},294    ethSigner,295    proxyContract.options.address,296    async (collection) => {297      const evmContract = await helper.ethNativeContract.collection(298        helper.ethAddress.fromCollectionId(collection.collectionId),299        'nft',300      );301302      await evmContract.methods.mintCross(303        helper.ethCrossAccount.fromAddress(receiverEthAddress),304        PROPERTIES.slice(0, setup.propertiesNumber),305      )306        .send({from: ethSigner});307    },308  );309310  const proxyContractFee = await calculateFeeNftMintWithProperties(311    helper,312    privateKey,313    {Ethereum: ethSigner},314    ethSigner,315    proxyContract.options.address,316    async (collection) => {317      await proxyContract.methods318        .mintToSubstrateWithProperty(319          helper.ethAddress.fromCollectionId(collection.collectionId),320          susbstrateReceiver.addressRaw,321          PROPERTIES.slice(0, setup.propertiesNumber),322        )323        .send({from: ethSigner});324    },325  );326327  const proxyContractBulkFee = await calculateFeeNftMintWithProperties(328    helper,329    privateKey,330    {Ethereum: ethSigner},331    ethSigner,332    proxyContract.options.address,333    async (collection) => {334      await proxyContract.methods335        .mintToSubstrateBulkProperty(336          helper.ethAddress.fromCollectionId(collection.collectionId),337          susbstrateReceiver.addressRaw,338          PROPERTIES.slice(0, setup.propertiesNumber),339        )340        .send({from: ethSigner, gas: 25_000_000});341    },342  );343344  return {345    propertiesNumber: setup.propertiesNumber,346    substrateFee: convertToTokens(substrateFee, nominal),347    ethFee: convertToTokens(ethFee, nominal),348    ethBulkFee: convertToTokens(ethBulkFee, nominal),349    ethMintCrossFee: convertToTokens(ethMintCrossFee, nominal),350    evmProxyContractFee: convertToTokens(proxyContractFee, nominal),351    evmProxyContractBulkFee: convertToTokens(proxyContractBulkFee, nominal),352  };353}354355async function calculateFeeNftMintWithProperties(356  helper: EthUniqueHelper,357  privateKey: (seed: string) => Promise<IKeyringPair>,358  payer: ICrossAccountId,359  ethSigner: string,360  proxyContractAddress: string,361  calculatedCall: (collection: UniqueNFTCollection) => Promise<any>,362): Promise<bigint> {363  const collection = (await createCollectionForBenchmarks(364    'nft',365    helper,366    privateKey,367    ethSigner,368    proxyContractAddress,369    PERMISSIONS,370  )) as UniqueNFTCollection;371  return helper.arrange.calculcateFee(payer, async () => {372    await calculatedCall(collection);373  });374}375376377