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

difftreelog

source

tests/src/benchmarks/mintFee/index.ts10.9 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 {convertToTokens, createCollectionForBenchmarks, PERMISSIONS, PROPERTIES} from '../utils/common';11import {makeNames} from '../../util';12import {ContractImports} from '../../eth/util/playgrounds/types';1314const {dirname} = makeNames(import.meta.url);1516export const CONTRACT_IMPORT: ContractImports[] = [17  {18    fsPath: `${dirname}/../../eth/api/CollectionHelpers.sol`,19    solPath: 'eth/api/CollectionHelpers.sol',20  },21  {22    fsPath: `${dirname}/../../eth/api/ContractHelpers.sol`,23    solPath: 'eth/api/ContractHelpers.sol',24  },25  {26    fsPath: `${dirname}/../../eth/api/UniqueRefungibleToken.sol`,27    solPath: 'eth/api/UniqueRefungibleToken.sol',28  },29  {30    fsPath: `${dirname}/../../eth/api/UniqueRefungible.sol`,31    solPath: 'eth/api/UniqueRefungible.sol',32  },33  {34    fsPath: `${dirname}/../../eth/api/UniqueNFT.sol`,35    solPath: 'eth/api/UniqueNFT.sol',36  },37];3839interface IBenchmarkResultForProp {40	propertiesNumber: number;41	substrateFee: number;42	ethFee: number;43	ethBulkFee: number;44  ethMintCrossFee: number;45	evmProxyContractFee: number;46	evmProxyContractBulkFee: number;47}4849const main = async () => {50  const benchmarks = [51    'substrateFee',52    'ethFee',53    'ethBulkFee',54    'ethMintCrossFee',55    'evmProxyContractFee',56    'evmProxyContractBulkFee',57  ];58  const headers = [59    'propertiesNumber',60    ...benchmarks,61  ];626364  const csvWriter = createObjectCsvWriter({65    path: 'properties.csv',66    header: headers,67  });6869  await usingEthPlaygrounds(async (helper, privateKey) => {70    const CONTRACT_SOURCE = (71      await readFile(`${dirname}/proxyContract.sol`)72    ).toString();7374    const donor = await privateKey('//Alice'); // Seed from account with balance on this network75    const ethSigner = await helper.eth.createAccountWithBalance(donor);7677    const contract = await helper.ethContract.deployByCode(78      ethSigner,79      'ProxyMint',80      CONTRACT_SOURCE,81      CONTRACT_IMPORT,82    );8384    const fees = await benchMintFee(helper, privateKey, contract);85    console.log('Minting without properties');86    console.table(fees);8788    const result: IBenchmarkResultForProp[] = [];89    const csvResult: IBenchmarkResultForProp[] = [];9091    for(let i = 1; i <= 20; i++) {92      const benchResult = await benchMintWithProperties(helper, privateKey, contract, {93        propertiesNumber: i,94      }) as any;9596      csvResult.push(benchResult);9798      const minFee = Math.min(...(benchmarks.map(x => benchResult[x])));99      for(const key of benchmarks) {100        const keyPercent = Math.round((benchResult[key] / minFee) * 100);101        benchResult[key] = `${benchResult[key]} (${keyPercent}%)`;102      }103104      result.push(benchResult);105    }106107    await csvWriter.writeRecords(csvResult);108109    console.log('Minting with properties');110    console.table(result, headers);111  });112};113114main()115  .then(() => process.exit(0))116  .catch((e) => {117    console.log(e);118    process.exit(1);119  });120121122123async function benchMintFee(124  helper: EthUniqueHelper,125  privateKey: (seed: string) => Promise<IKeyringPair>,126  proxyContract: Contract,127): Promise<{128	substrateFee: number;129	ethFee: number;130	evmProxyContractFee: number;131}> {132  const donor = await privateKey('//Alice');133  const substrateReceiver = await privateKey('//Bob');134  const ethSigner = await helper.eth.createAccountWithBalance(donor);135136  const nominal = helper.balance.getOneTokenNominal();137138  await helper.eth.transferBalanceFromSubstrate(139    donor,140    proxyContract.options.address,141    100n,142  );143144  const collection = (await createCollectionForBenchmarks(145    'nft',146    helper,147    privateKey,148    ethSigner,149    proxyContract.options.address,150    PERMISSIONS,151  )) as UniqueNFTCollection;152153  const substrateFee = await helper.arrange.calculcateFee(154    {Substrate: donor.address},155    () => collection.mintToken(donor, {Substrate: substrateReceiver.address}),156  );157158  const collectionEthAddress = helper.ethAddress.fromCollectionId(collection.collectionId);159  const collectionContract = await helper.ethNativeContract.collection(160    collectionEthAddress,161    'nft',162  );163164  const receiverEthAddress = helper.address.substrateToEth(substrateReceiver.address);165166  const encodedCall = collectionContract.methods167    .mint(receiverEthAddress)168    .encodeABI();169170  const ethFee = await helper.arrange.calculcateFee(171    {Substrate: donor.address},172    async () => {173      await helper.eth.sendEVM(174        donor,175        collectionContract.options.address,176        encodedCall,177        '0',178      );179    },180  );181182  const evmProxyContractFee = await helper.arrange.calculcateFee(183    {Ethereum: ethSigner},184    async () => {185      await proxyContract.methods186        .mintToSubstrate(187          helper.ethAddress.fromCollectionId(collection.collectionId),188          substrateReceiver.addressRaw,189        )190        .send({from: ethSigner});191    },192  );193194  return {195    substrateFee: convertToTokens(substrateFee, nominal),196    ethFee: convertToTokens(ethFee, nominal),197    evmProxyContractFee: convertToTokens(evmProxyContractFee, nominal),198  };199}200201async function benchMintWithProperties(202  helper: EthUniqueHelper,203  privateKey: (seed: string) => Promise<IKeyringPair>,204  proxyContract: Contract,205  setup: { propertiesNumber: number },206): Promise<IBenchmarkResultForProp> {207  const donor = await privateKey('//Alice'); // Seed from account with balance on this network208  const ethSigner = await helper.eth.createAccountWithBalance(donor);209210  const susbstrateReceiver = await privateKey('//Bob');211  const receiverEthAddress = helper.address.substrateToEth(susbstrateReceiver.address);212213  const nominal = helper.balance.getOneTokenNominal();214215  const substrateFee = await calculateFeeNftMintWithProperties(216    helper,217    privateKey,218    {Substrate: donor.address},219    ethSigner,220    proxyContract.options.address,221    async (collection) => {222      await collection.mintToken(223        donor,224        {Substrate: susbstrateReceiver.address},225        PROPERTIES.slice(0, setup.propertiesNumber).map((p) => ({key: p.key, value: Buffer.from(p.value).toString()})),226      );227    },228  );229230  const ethFee = await calculateFeeNftMintWithProperties(231    helper,232    privateKey,233    {Substrate: donor.address},234    ethSigner,235    proxyContract.options.address,236    async (collection) => {237      const evmContract = await helper.ethNativeContract.collection(238        helper.ethAddress.fromCollectionId(collection.collectionId),239        'nft',240        undefined,241        true,242      );243244      const subTokenId = await evmContract.methods.nextTokenId().call();245246      let encodedCall = evmContract.methods247        .mint(receiverEthAddress)248        .encodeABI();249250      await helper.eth.sendEVM(251        donor,252        evmContract.options.address,253        encodedCall,254        '0',255      );256257      for(const val of PROPERTIES.slice(0, setup.propertiesNumber)) {258        encodedCall = await evmContract.methods259          .setProperty(subTokenId, val.key, Buffer.from(val.value))260          .encodeABI();261262        await helper.eth.sendEVM(263          donor,264          evmContract.options.address,265          encodedCall,266          '0',267        );268      }269    },270  );271272  const ethBulkFee = await calculateFeeNftMintWithProperties(273    helper,274    privateKey,275    {Substrate: donor.address},276    ethSigner,277    proxyContract.options.address,278    async (collection) => {279      const evmContract = await helper.ethNativeContract.collection(280        helper.ethAddress.fromCollectionId(collection.collectionId),281        'nft',282      );283284      const subTokenId = await evmContract.methods.nextTokenId().call();285286      let encodedCall = evmContract.methods287        .mint(receiverEthAddress)288        .encodeABI();289290      await helper.eth.sendEVM(291        donor,292        evmContract.options.address,293        encodedCall,294        '0',295      );296297      encodedCall = await evmContract.methods298        .setProperties(299          subTokenId,300          PROPERTIES.slice(0, setup.propertiesNumber),301        )302        .encodeABI();303304      await helper.eth.sendEVM(305        donor,306        evmContract.options.address,307        encodedCall,308        '0',309      );310    },311  );312313  const ethMintCrossFee = await calculateFeeNftMintWithProperties(314    helper,315    privateKey,316    {Ethereum: ethSigner},317    ethSigner,318    proxyContract.options.address,319    async (collection) => {320      const evmContract = await helper.ethNativeContract.collection(321        helper.ethAddress.fromCollectionId(collection.collectionId),322        'nft',323      );324325      await evmContract.methods.mintCross(326        helper.ethCrossAccount.fromAddress(receiverEthAddress),327        PROPERTIES.slice(0, setup.propertiesNumber),328      )329        .send({from: ethSigner});330    },331  );332333  const proxyContractFee = await calculateFeeNftMintWithProperties(334    helper,335    privateKey,336    {Ethereum: ethSigner},337    ethSigner,338    proxyContract.options.address,339    async (collection) => {340      await proxyContract.methods341        .mintToSubstrateWithProperty(342          helper.ethAddress.fromCollectionId(collection.collectionId),343          susbstrateReceiver.addressRaw,344          PROPERTIES.slice(0, setup.propertiesNumber),345        )346        .send({from: ethSigner});347    },348  );349350  const proxyContractBulkFee = await calculateFeeNftMintWithProperties(351    helper,352    privateKey,353    {Ethereum: ethSigner},354    ethSigner,355    proxyContract.options.address,356    async (collection) => {357      await proxyContract.methods358        .mintToSubstrateBulkProperty(359          helper.ethAddress.fromCollectionId(collection.collectionId),360          susbstrateReceiver.addressRaw,361          PROPERTIES.slice(0, setup.propertiesNumber),362        )363        .send({from: ethSigner});364    },365  );366367  return {368    propertiesNumber: setup.propertiesNumber,369    substrateFee: convertToTokens(substrateFee, nominal),370    ethFee: convertToTokens(ethFee, nominal),371    ethBulkFee: convertToTokens(ethBulkFee, nominal),372    ethMintCrossFee: convertToTokens(ethMintCrossFee, nominal),373    evmProxyContractFee: convertToTokens(proxyContractFee, nominal),374    evmProxyContractBulkFee: convertToTokens(proxyContractBulkFee, nominal),375  };376}377378async function calculateFeeNftMintWithProperties(379  helper: EthUniqueHelper,380  privateKey: (seed: string) => Promise<IKeyringPair>,381  payer: ICrossAccountId,382  ethSigner: string,383  proxyContractAddress: string,384  calculatedCall: (collection: UniqueNFTCollection) => Promise<any>,385): Promise<bigint> {386  const collection = (await createCollectionForBenchmarks(387    'nft',388    helper,389    privateKey,390    ethSigner,391    proxyContractAddress,392    PERMISSIONS,393  )) as UniqueNFTCollection;394  return helper.arrange.calculcateFee(payer, async () => {395    await calculatedCall(collection);396  });397}398399400