diff --git a/packages/api-database/source/search/filters/wallet-filter.ts b/packages/api-database/source/search/filters/wallet-filter.ts index 7be905e676..e0e21addc4 100644 --- a/packages/api-database/source/search/filters/wallet-filter.ts +++ b/packages/api-database/source/search/filters/wallet-filter.ts @@ -106,7 +106,7 @@ export class WalletFilter { walletAttributeRepository.set("publicKey", Contracts.State.AttributeType.String); walletAttributeRepository.set("username", Contracts.State.AttributeType.String); walletAttributeRepository.set("validatorPublicKey", Contracts.State.AttributeType.String); - walletAttributeRepository.set("validatorRank", Contracts.State.AttributeType.Number); + walletAttributeRepository.set("validatorRank", Contracts.State.AttributeType.Number); walletAttributeRepository.set("validatorVoteBalance", Contracts.State.AttributeType.BigNumber); walletAttributeRepository.set("validatorLastBlock", Contracts.State.AttributeType.Object); walletAttributeRepository.set("validatorForgedFees", Contracts.State.AttributeType.BigNumber); diff --git a/packages/api-development/source/controllers/round.ts b/packages/api-development/source/controllers/round.ts index 3acaa34342..283b4aeb9e 100644 --- a/packages/api-development/source/controllers/round.ts +++ b/packages/api-development/source/controllers/round.ts @@ -32,7 +32,7 @@ export class RoundController extends Controller { ...this.roundCalculator.calculateRound(blockNumber), // Map the round validator set (static, vote-weighted, etc.) to actual proposal order validators: orderedValidators.map((validator) => ({ - voteBalance: validator.voteBalance.toFixed(), + voteBalance: validator.voteBalance.toString(), wallet: validator, })), diff --git a/packages/api-http/source/controllers/commits.ts b/packages/api-http/source/controllers/commits.ts index 1290665e22..82f832422a 100644 --- a/packages/api-http/source/controllers/commits.ts +++ b/packages/api-http/source/controllers/commits.ts @@ -3,7 +3,7 @@ import type { Types } from "@mainsail/api-common"; import Boom from "@hapi/boom"; import { Contracts as ApiDatabaseContracts, Identifiers as ApiDatabaseIdentifiers } from "@mainsail/api-database"; import { inject, injectable } from "@mainsail/container"; -import { BigNumber, validatorSetUnpack } from "@mainsail/utils"; +import { validatorSetUnpack } from "@mainsail/utils"; import { Controller } from "./controller.js"; @@ -35,7 +35,7 @@ export class CommitsController extends Controller { if (round) { // map bitmask -> indexes -> round.validators - const packed = BigNumber.make(block.validatorSet).toBigInt(); + const packed = BigInt(block.validatorSet); const unpacked = validatorSetUnpack(packed, round.validators.length); validators = unpacked.filter(Boolean).map((_, index) => round.validators[index]); } diff --git a/packages/api-http/source/resources/block.ts b/packages/api-http/source/resources/block.ts index 199facf20a..d79c3ce409 100644 --- a/packages/api-http/source/resources/block.ts +++ b/packages/api-http/source/resources/block.ts @@ -2,7 +2,6 @@ import type { Contracts } from "@mainsail/contracts"; import { Models } from "@mainsail/api-database"; import { injectable } from "@mainsail/container"; -import { BigNumber } from "@mainsail/utils"; export interface EnrichedBlock extends Models.Block { state: Models.State; @@ -32,7 +31,7 @@ export class BlockResource implements Contracts.Api.Resource { round: resource.round, signature: resource.signature, timestamp: resource.timestamp, - total: BigNumber.make(resource.reward).plus(resource.fee).toFixed(), + total: (BigInt(resource.reward) + BigInt(resource.fee)).toString(), transactionsCount: resource.transactionsCount, transactionsRoot: resource.transactionsRoot, username: resource.generator.attributes?.["username"] ?? undefined, diff --git a/packages/api-sync/source/restore.ts b/packages/api-sync/source/restore.ts index dd0d1d1f38..738a998f00 100644 --- a/packages/api-sync/source/restore.ts +++ b/packages/api-sync/source/restore.ts @@ -9,7 +9,7 @@ import { Identifiers } from "@mainsail/constants"; import { inject, injectable, optional, tagged } from "@mainsail/container"; import { Deployer, Identifiers as EvmConsensusIdentifiers } from "@mainsail/evm-consensus"; import { parseTransactionError } from "@mainsail/evm-contracts"; -import { assert, BigNumber, chunk, formatEcdsaSignature, validatorSetPack } from "@mainsail/utils"; +import { assert, chunk, formatEcdsaSignature, validatorSetPack } from "@mainsail/utils"; import { performance } from "perf_hooks"; import { TokenParser } from "./contracts.js"; @@ -42,7 +42,7 @@ interface RestoreContext extends RepositoryContext { mostRecentCommit: Contracts.Crypto.Commit; lastBlockNumber: number; - totalSupply: BigNumber; + totalSupply: bigint; validatorAttributes: Record; userAttributes: Record; @@ -52,12 +52,12 @@ interface RestoreContext extends RepositoryContext { interface ValidatorAttributes { lastBlock?: Contracts.Crypto.BlockHeader; - totalForgedFees: BigNumber; - totalForgedRewards: BigNumber; + totalForgedFees: bigint; + totalForgedRewards: bigint; producedBlocks: number; - voteBalance: BigNumber; - fee: BigNumber; + voteBalance: bigint; + fee: bigint; votersCount: number; blsPublicKey: string; isResigned: boolean; @@ -203,7 +203,7 @@ export class Restore { tokenHolderRepository: this.tokenHolderRepositoryFactory(entityManager), tokenRepository: this.tokenRepositoryFactory(entityManager), - totalSupply: BigNumber.ZERO, + totalSupply: 0n, transactionRepository: this.transactionRepositoryFactory(entityManager), userAttributes: {}, validatorAttributes: {}, @@ -414,8 +414,8 @@ export class Restore { } } else { validatorAttributes.producedBlocks += 1; - validatorAttributes.totalForgedFees = validatorAttributes.totalForgedFees.plus(block.fee); - validatorAttributes.totalForgedRewards = validatorAttributes.totalForgedRewards.plus(block.reward); + validatorAttributes.totalForgedFees += block.fee; + validatorAttributes.totalForgedRewards += block.reward; validatorAttributes.lastBlock = block; } @@ -571,8 +571,8 @@ export class Restore { fee: validator.fee, isResigned: validator.isResigned, producedBlocks: 0, - totalForgedFees: BigNumber.ZERO, - totalForgedRewards: BigNumber.ZERO, + totalForgedFees: 0n, + totalForgedRewards: 0n, voteBalance: validator.voteBalance, votersCount: validator.votersCount, }; @@ -648,25 +648,25 @@ export class Restore { attributes: { ...(validatorAttributes ? { - validatorFee: validatorAttributes.fee, + validatorFee: validatorAttributes.fee.toString(), validatorPublicKey: validatorAttributes.blsPublicKey, validatorResigned: validatorAttributes.isResigned, - validatorVoteBalance: validatorAttributes.voteBalance, + validatorVoteBalance: validatorAttributes.voteBalance.toString(), validatorVotersCount: validatorAttributes.votersCount, - ...(validatorAttributes.totalForgedFees.isGreaterThan(0) - ? { validatorForgedFees: validatorAttributes.totalForgedFees.toFixed() } + ...(validatorAttributes.totalForgedFees > 0n + ? { validatorForgedFees: validatorAttributes.totalForgedFees.toString() } : {}), - ...(validatorAttributes.totalForgedRewards.isGreaterThan(0) - ? { validatorForgedRewards: validatorAttributes.totalForgedRewards.toFixed() } + ...(validatorAttributes.totalForgedRewards > 0n + ? { validatorForgedRewards: validatorAttributes.totalForgedRewards.toString() } : {}), - ...(validatorAttributes.totalForgedFees - .plus(validatorAttributes.totalForgedRewards) - .isGreaterThan(0) + ...(validatorAttributes.totalForgedFees + validatorAttributes.totalForgedRewards > + 0n ? { - validatorForgedTotal: validatorAttributes.totalForgedFees - .plus(validatorAttributes.totalForgedRewards) - .toFixed(), + validatorForgedTotal: ( + validatorAttributes.totalForgedFees + + validatorAttributes.totalForgedRewards + ).toString(), } : {}), ...(validatorAttributes.producedBlocks > 0 @@ -720,8 +720,8 @@ export class Restore { } : {}), } as string, // is converted into JSONB column - balance: BigNumber.make(account.balance).toFixed(), - nonce: BigNumber.make(account.nonce).toFixed(), + balance: account.balance.toString(), + nonce: account.nonce.toString(), publicKey: context.addressToPublicKey[account.address] ?? null, updated_at: "0", }); @@ -737,7 +737,7 @@ export class Restore { offset = result.nextOffset; } while (offset); - context.totalSupply = context.totalSupply.plus(totalAccountBalance); + context.totalSupply += totalAccountBalance; const t1 = performance.now(); this.logger.info(`Restored ${totalAccounts.toLocaleString()} wallets in ${t1 - t0}ms`); @@ -761,7 +761,7 @@ export class Restore { for (const wallet of result.wallets) { legacyColdWallets.push({ address: wallet.address, - balance: BigNumber.make(wallet.balance).toFixed(), + balance: wallet.balance.toString(), ...(Object.keys(wallet.legacyAttributes).length > 0 ? { attributes: { @@ -804,7 +804,7 @@ export class Restore { offset = result.nextOffset; } while (offset); - context.totalSupply = context.totalSupply.plus(totalLegacyAccountBalance); + context.totalSupply += totalLegacyAccountBalance; const t1 = performance.now(); this.logger.info(`Restored ${totalLegacyAccounts.toLocaleString()} legacy cold wallets in ${t1 - t0}ms`); @@ -855,7 +855,7 @@ export class Restore { const proposer = validators[proposerIndex]; validatorAddresses[index] = proposer.address; - votes[index] = proposer.voteBalance.toFixed(); + votes[index] = proposer.voteBalance.toString(); } validatorRoundsToIngest.push({ @@ -899,7 +899,7 @@ export class Restore { .values({ blockNumber: context.lastBlockNumber.toFixed(), id: 1, - supply: context.totalSupply.toFixed(), + supply: context.totalSupply.toString(), }) .execute(); } diff --git a/packages/api-sync/source/service.ts b/packages/api-sync/source/service.ts index d3fc830f46..dedb64e55f 100644 --- a/packages/api-sync/source/service.ts +++ b/packages/api-sync/source/service.ts @@ -10,7 +10,7 @@ import { Identifiers } from "@mainsail/constants"; import { inject, injectable, tagged } from "@mainsail/container"; import { Identifiers as EvmConsensusIdentifiers } from "@mainsail/evm-consensus"; import { parseTransactionError } from "@mainsail/evm-contracts"; -import { assert, BigNumber, chunk, formatEcdsaSignature, sleep, validatorSetPack } from "@mainsail/utils"; +import { assert, chunk, formatEcdsaSignature, sleep, validatorSetPack } from "@mainsail/utils"; import { performance } from "perf_hooks"; import { Listeners, TokenParser } from "./contracts.js"; @@ -263,10 +263,10 @@ export class Sync implements Contracts.ApiSync.Service { return { ...(dirtyValidator ? { - validatorFee: dirtyValidator.fee, + validatorFee: dirtyValidator.fee.toString(), validatorPublicKey: dirtyValidator.blsPublicKey, validatorResigned: dirtyValidator.isResigned, - validatorVoteBalance: dirtyValidator.voteBalance, + validatorVoteBalance: dirtyValidator.voteBalance.toString(), validatorVotersCount: dirtyValidator.votersCount, // updated at end of db transaction // - validatorRank @@ -313,8 +313,8 @@ export class Sync implements Contracts.ApiSync.Service { return [ account.address, addressToPublicKey[account.address] ?? null, - BigNumber.make(account.balance).toFixed(), - BigNumber.make(account.nonce).toFixed(), + account.balance.toString(), + account.nonce.toString(), attributes, header.number.toFixed(), ]; @@ -400,7 +400,7 @@ export class Sync implements Contracts.ApiSync.Service { return { ...this.roundCalculator.calculateRound(number), validators: validatorWallets.map((v) => v.address), - votes: validatorWallets.map((v) => v.voteBalance.toFixed()), + votes: validatorWallets.map((v) => v.voteBalance.toString()), }; } @@ -470,7 +470,7 @@ export class Sync implements Contracts.ApiSync.Service { }) .where("id = :id", { id: 1 }) .andWhere("blockNumber = :previousBlockNumber", { - previousBlockNumber: BigNumber.make(deferred.block.number).minus(1).toFixed(), + previousBlockNumber: (BigInt(deferred.block.number) - 1n).toString(), }) .execute(); diff --git a/packages/blockchain-utils/source/fee-calculator.test.ts b/packages/blockchain-utils/source/fee-calculator.test.ts index 33399810d8..0939caba06 100644 --- a/packages/blockchain-utils/source/fee-calculator.test.ts +++ b/packages/blockchain-utils/source/fee-calculator.test.ts @@ -7,10 +7,10 @@ describe("FeeCalculator", ({ assert, it }) => { it("should calculate gas consumed", async () => { const feeCalculator = new FeeCalculator(); - assert.equal(feeCalculator.calculateConsumed(5 * 1e9, 21_000).toBigInt(), 105_000_000_000_000n); + assert.equal(feeCalculator.calculateConsumed(5 * 1e9, 21_000n), 105_000_000_000_000n); assert.equal( - feeCalculator.calculate({ gasLimit: 21_000, gasPrice: 5 * 1e9 } as Contracts.Crypto.Transaction).toBigInt(), + feeCalculator.calculate({ gasLimit: 21_000, gasPrice: 5 * 1e9 } as Contracts.Crypto.Transaction), 105_000_000_000_000n, ); }); diff --git a/packages/blockchain-utils/source/fee-calculator.ts b/packages/blockchain-utils/source/fee-calculator.ts index b65942bcbb..51968ecafa 100644 --- a/packages/blockchain-utils/source/fee-calculator.ts +++ b/packages/blockchain-utils/source/fee-calculator.ts @@ -1,15 +1,14 @@ import type { Contracts } from "@mainsail/contracts"; import { injectable } from "@mainsail/container"; -import { BigNumber } from "@mainsail/utils"; @injectable() export class FeeCalculator implements Contracts.BlockchainUtils.FeeCalculator { - public calculate(transaction: Contracts.Crypto.Transaction): BigNumber { - return BigNumber.make(transaction.gasPrice).times(transaction.gasLimit); + public calculate(transaction: Contracts.Crypto.Transaction): bigint { + return BigInt(transaction.gasPrice) * BigInt(transaction.gasLimit); } - public calculateConsumed(gasPrice: number, gasUsed: number): BigNumber { - return BigNumber.make(gasPrice).times(gasUsed); + public calculateConsumed(gasPrice: number, gasUsed: bigint): bigint { + return BigInt(gasPrice) * gasUsed; } } diff --git a/packages/blockchain-utils/source/format.test.ts b/packages/blockchain-utils/source/format.test.ts index 2c777e1e49..4f82590805 100644 --- a/packages/blockchain-utils/source/format.test.ts +++ b/packages/blockchain-utils/source/format.test.ts @@ -1,5 +1,4 @@ import { Identifiers } from "@mainsail/constants"; -import { BigNumber } from "@mainsail/utils"; import { ServiceProvider as ValidationServiceProvider } from "@mainsail/validation"; import { ServiceProvider as CryptoConfigServiceProvider } from "@mainsail/crypto-config"; import crypto from "../../core/bin/config/devnet/core/crypto.json"; @@ -23,9 +22,9 @@ describe<{ }); it("should format currency", ({ configuration }) => { - assert.equal(formatCurrency(configuration, BigNumber.ONE), "0.000000000000000001 TѦ"); - assert.equal(formatCurrency(configuration, BigNumber.ZERO), "0 TѦ"); - assert.equal(formatCurrency(configuration, BigNumber.make(1e18)), "1 TѦ"); - assert.equal(formatCurrency(configuration, BigNumber.make(1e18).times(100)), "100 TѦ"); + assert.equal(formatCurrency(configuration, 1n), "0.000000000000000001 TѦ"); + assert.equal(formatCurrency(configuration, 0n), "0 TѦ"); + assert.equal(formatCurrency(configuration, BigInt(1e18)), "1 TѦ"); + assert.equal(formatCurrency(configuration, BigInt(1e18) * 100n), "100 TѦ"); }); }); diff --git a/packages/blockchain-utils/source/format.ts b/packages/blockchain-utils/source/format.ts index 2494d37a41..15b4582945 100644 --- a/packages/blockchain-utils/source/format.ts +++ b/packages/blockchain-utils/source/format.ts @@ -1,10 +1,19 @@ import type { Contracts } from "@mainsail/contracts"; -import type { BigNumber } from "@mainsail/utils"; -export const formatCurrency = (configuration: Contracts.Crypto.Configuration, amount: BigNumber): string => { +type FractionDigit = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20; + +function isFractionDigit(n: number): n is FractionDigit { + return n >= 0 && n <= 20 && Number.isInteger(n); +} + +export const formatCurrency = (configuration: Contracts.Crypto.Configuration, amount: bigint): string => { const { decimals, denomination } = configuration.getMilestone().satoshi; - const localeString = (+amount / denomination).toLocaleString("en", { + if (!isFractionDigit(decimals)) { + throw new Error("Invalid decimals"); + } + + const localeString = (Number(amount) / denomination).toLocaleString("en", { maximumFractionDigits: decimals, minimumFractionDigits: 0, }); diff --git a/packages/configuration-generator/source/configuration-generator.test.ts b/packages/configuration-generator/source/configuration-generator.test.ts index b638bfd0cb..42bca1a335 100644 --- a/packages/configuration-generator/source/configuration-generator.test.ts +++ b/packages/configuration-generator/source/configuration-generator.test.ts @@ -1,5 +1,4 @@ import { Application } from "@mainsail/kernel"; -import { BigNumber } from "@mainsail/utils"; import envPaths from "env-paths"; import fs from "fs-extra/esm"; import { join } from "path"; @@ -53,10 +52,10 @@ describe<{ payloadHash: match.string, payloadLength: match.number, previousBlock: "0000000000000000000000000000000000000000000000000000000000000000", - reward: BigNumber.ZERO, + reward: 0n, timestamp: match.number, - totalAmount: BigNumber.make("12500000000000000"), - totalFee: BigNumber.ZERO, + totalAmount: 12500000000000000n, + totalFee: 0n, transactions: match.array, version: 1, }, @@ -189,10 +188,10 @@ describe<{ payloadHash: match.string, payloadLength: match.number, previousBlock: "0000000000000000000000000000000000000000000000000000000000000000", - reward: BigNumber.ZERO, + reward: 0n, timestamp: match.number, - totalAmount: BigNumber.make("12499999999999969"), - totalFee: BigNumber.ZERO, + totalAmount: 12499999999999969n, + totalFee: 0n, transactions: match.array, version: 1, }, diff --git a/packages/configuration-generator/source/generators/genesis-block.ts b/packages/configuration-generator/source/generators/genesis-block.ts index 2817003854..a7e8f54ee3 100644 --- a/packages/configuration-generator/source/generators/genesis-block.ts +++ b/packages/configuration-generator/source/generators/genesis-block.ts @@ -5,7 +5,7 @@ import { inject, injectable, optional, tagged } from "@mainsail/container"; import { TransactionBuilder } from "@mainsail/crypto-transaction"; import { Deployer, Identifiers as EvmConsensusIdentifiers } from "@mainsail/evm-consensus"; import { ConsensusAbi } from "@mainsail/evm-contracts"; -import { assert, BigNumber } from "@mainsail/utils"; +import { assert } from "@mainsail/utils"; import dayjs from "dayjs"; import { encodeFunctionData } from "viem"; @@ -62,8 +62,8 @@ export class GenesisBlockGenerator extends Generator { ); options.premine = transactions - .reduce((accumulator, current) => accumulator.plus(current.value), BigNumber.ZERO) - .toFixed(); + .reduce((accumulator, current) => accumulator + current.value, 0n) + .toString(); } else { transactions = transactions.concat( await this.#createTransferTransaction( @@ -113,8 +113,8 @@ export class GenesisBlockGenerator extends Generator { : options.initialBlockNumber, initialSupply: (options.distribute ? // Ensure no left over remains when distributing funds from the genesis address (see `#createTransferTransactions`) - BigNumber.make(options.premine).dividedBy(validatorsCount).times(validatorsCount) - : BigNumber.make(options.premine) + (BigInt(options.premine) / BigInt(validatorsCount)) * BigInt(validatorsCount) + : BigInt(options.premine) ).toString(), timestamp: dayjs(options.epoch).valueOf(), }); @@ -151,7 +151,7 @@ export class GenesisBlockGenerator extends Generator { totalPremine: string, chainId: number, ): Promise { - const amount: string = BigNumber.make(totalPremine).dividedBy(recipients.length).toString(); + const amount: string = (BigInt(totalPremine) / BigInt(recipients.length)).toString(); const result: Contracts.Crypto.Transaction[] = []; @@ -248,8 +248,8 @@ export class GenesisBlockGenerator extends Generator { transactions: Contracts.Crypto.Transaction[], options: Contracts.NetworkGenerator.InternalOptions, ): Promise<{ block: Contracts.Crypto.Block; transactions: Contracts.Crypto.TransactionData[] }> { - const totals: { fee: BigNumber; gasUsed: number } = { - fee: BigNumber.ZERO, + const totals: { fee: bigint; gasUsed: number } = { + fee: 0n, gasUsed: 0, }; @@ -295,7 +295,7 @@ export class GenesisBlockGenerator extends Generator { value: transaction.value, }); - totals.fee = totals.fee.plus(transaction.gasPrice); + totals.fee += BigInt(transaction.gasPrice); totals.gasUsed += Number(receipt.gasUsed); payloadBuffers.push(Buffer.from(transaction.hash, "hex")); @@ -313,7 +313,7 @@ export class GenesisBlockGenerator extends Generator { await this.evm.calculateRoundValidators({ commitKey, - roundValidators: BigNumber.make(options.validators).toBigInt(), + roundValidators: BigInt(options.validators), specId: Enums.Evm.SpecId.SHANGHAI, timestamp, validatorAddress: proposer, @@ -322,7 +322,7 @@ export class GenesisBlockGenerator extends Generator { return { block: await this.app.get(Identifiers.Cryptography.Block.Factory).make( { - fee: totals.fee.toBigInt(), + fee: totals.fee, gasUsed: totals.gasUsed, logsBloom: await this.evm.logsBloom(commitKey), number: options.initialBlockNumber ?? 0, diff --git a/packages/consensus/source/consensus.ts b/packages/consensus/source/consensus.ts index cab741b605..6c5d66fa2e 100644 --- a/packages/consensus/source/consensus.ts +++ b/packages/consensus/source/consensus.ts @@ -2,11 +2,11 @@ import type { Contracts } from "@mainsail/contracts"; import { Enums, Events, Identifiers, Locale } from "@mainsail/constants"; import { inject, injectable } from "@mainsail/container"; -import { assert, BigNumber, Lock } from "@mainsail/utils"; +import { assert, Lock } from "@mainsail/utils"; import dayjs from "dayjs"; const FAILED_PROCESSOR_RESULT: Contracts.Processor.BlockProcessorResult = { - feeUsed: BigNumber.ZERO, + feeUsed: 0n, gasUsed: 0, receipts: new Map(), success: false, diff --git a/packages/contracts/source/contracts/blockchain-utils.ts b/packages/contracts/source/contracts/blockchain-utilities.ts similarity index 78% rename from packages/contracts/source/contracts/blockchain-utils.ts rename to packages/contracts/source/contracts/blockchain-utilities.ts index 47d1ad0b86..ace2636168 100644 --- a/packages/contracts/source/contracts/blockchain-utils.ts +++ b/packages/contracts/source/contracts/blockchain-utilities.ts @@ -1,11 +1,9 @@ -import type { BigNumber } from "@mainsail/utils"; - import type { Block, Transaction } from "./crypto/index.js"; import type { RoundInfo } from "./shared/rounds.js"; export interface FeeCalculator { - calculate(transaction: Transaction): BigNumber; - calculateConsumed(gasPrice: number, gasUsed: number): BigNumber; + calculate(transaction: Transaction): bigint; + calculateConsumed(gasPrice: number, gasUsed: bigint): bigint; } export interface RoundCalculator { diff --git a/packages/contracts/source/contracts/evm/contract-service.ts b/packages/contracts/source/contracts/evm/contract-service.ts index 8063e871a0..a7735e4316 100644 --- a/packages/contracts/source/contracts/evm/contract-service.ts +++ b/packages/contracts/source/contracts/evm/contract-service.ts @@ -1,5 +1,3 @@ -import type { BigNumber } from "@mainsail/utils"; - import type { ValidatorWallet } from "../state/wallets.js"; export interface DeployerContract { @@ -16,7 +14,7 @@ export interface Vote { } export interface ValidatorRoundValidator { - readonly voteBalance: BigNumber; + readonly voteBalance: bigint; readonly address: string; } diff --git a/packages/contracts/source/contracts/index.ts b/packages/contracts/source/contracts/index.ts index 5cf3d8a4b6..622e089414 100644 --- a/packages/contracts/source/contracts/index.ts +++ b/packages/contracts/source/contracts/index.ts @@ -1,6 +1,6 @@ export * as ApiSync from "./api-sync.js"; export * as Api from "./api/index.js"; -export * as BlockchainUtils from "./blockchain-utils.js"; +export * as BlockchainUtils from "./blockchain-utilities.js"; export * as Cli from "./cli/index.js"; export * as ConsensusStorage from "./consensus-storage.js"; export * as Consensus from "./consensus/index.js"; diff --git a/packages/contracts/source/contracts/processor/block-processor-result.ts b/packages/contracts/source/contracts/processor/block-processor-result.ts index 8495fc926b..018042f517 100644 --- a/packages/contracts/source/contracts/processor/block-processor-result.ts +++ b/packages/contracts/source/contracts/processor/block-processor-result.ts @@ -1,10 +1,8 @@ -import type { BigNumber } from "@mainsail/utils"; - import type { TransactionReceipt } from "../evm/evm.js"; export interface BlockProcessorResult { success: boolean; receipts: Map; gasUsed: number; - feeUsed: BigNumber; + feeUsed: bigint; } diff --git a/packages/contracts/source/contracts/state/wallets.ts b/packages/contracts/source/contracts/state/wallets.ts index 0164a22fdb..5fe4e188ef 100644 --- a/packages/contracts/source/contracts/state/wallets.ts +++ b/packages/contracts/source/contracts/state/wallets.ts @@ -1,15 +1,13 @@ -import type { BigNumber } from "@mainsail/utils"; - export interface Wallet { getAddress(): string; - getBalance(): BigNumber; - setBalance(balance: BigNumber): void; - increaseBalance(balance: BigNumber): Wallet; - decreaseBalance(balance: BigNumber): Wallet; + getBalance(): bigint; + setBalance(balance: bigint): void; + increaseBalance(balance: bigint): Wallet; + decreaseBalance(balance: bigint): Wallet; - getNonce(): BigNumber; - setNonce(nonce: BigNumber): void; + getNonce(): bigint; + setNonce(nonce: bigint): void; increaseNonce(): void; decreaseNonce(): void; @@ -22,8 +20,8 @@ export interface Wallet { export interface ValidatorWallet { address: string; blsPublicKey: string; - voteBalance: BigNumber; + voteBalance: bigint; votersCount: number; - fee: BigNumber; + fee: bigint; isResigned: boolean; } diff --git a/packages/contracts/source/contracts/transaction-pool/sender-mempool.ts b/packages/contracts/source/contracts/transaction-pool/sender-mempool.ts index 0b732e980e..d785109dfa 100644 --- a/packages/contracts/source/contracts/transaction-pool/sender-mempool.ts +++ b/packages/contracts/source/contracts/transaction-pool/sender-mempool.ts @@ -1,11 +1,9 @@ -import type { BigNumber } from "@mainsail/utils"; - import type { Transaction } from "../crypto/transactions.js"; export interface SenderMempool { isDisposable(): boolean; getSize(): number; - getNonce(): BigNumber; + getNonce(): bigint; getFromEarliest(): Iterable; getFromLatest(): Iterable; diff --git a/packages/contracts/source/contracts/transaction-pool/sender-state.ts b/packages/contracts/source/contracts/transaction-pool/sender-state.ts index a874ecd562..9d29018b39 100644 --- a/packages/contracts/source/contracts/transaction-pool/sender-state.ts +++ b/packages/contracts/source/contracts/transaction-pool/sender-state.ts @@ -1,5 +1,3 @@ -import type { BigNumber } from "@mainsail/utils"; - import type { Transaction } from "../crypto/transactions.js"; export interface SenderState { @@ -7,6 +5,6 @@ export interface SenderState { reset(): Promise; apply(transaction: Transaction): Promise; revert(transaction: Transaction): void; - replace(oldTransaction: Transaction, newTransaction: Transaction, nonceOffset: BigNumber): Promise; - getNonce(): BigNumber; + replace(oldTransaction: Transaction, newTransaction: Transaction, nonceOffset: bigint): Promise; + getNonce(): bigint; } diff --git a/packages/contracts/source/contracts/webhooks.ts b/packages/contracts/source/contracts/webhooks.ts index 8d99dfd772..dee3b97a1b 100644 --- a/packages/contracts/source/contracts/webhooks.ts +++ b/packages/contracts/source/contracts/webhooks.ts @@ -1,5 +1,4 @@ -import type { BigNumberType } from "@mainsail/utils"; - +export type BigNumberType = bigint | number | string; export type ConditionPrimitive = string | number | boolean; export type ConditionBigNumberish = Exclude; export type ConditionRange = { min: ConditionBigNumberish; max: ConditionBigNumberish }; diff --git a/packages/core/source/commands/config-generate.test.ts b/packages/core/source/commands/config-generate.test.ts index b3bc3e8888..068ce28e14 100644 --- a/packages/core/source/commands/config-generate.test.ts +++ b/packages/core/source/commands/config-generate.test.ts @@ -1,4 +1,3 @@ -import { BigNumber } from "@mainsail/utils"; import envPaths from "env-paths"; import fs from "fs"; import { join } from "path"; @@ -64,10 +63,10 @@ describe<{ payloadHash: match.string, payloadLength: match.number, previousBlock: "0000000000000000000000000000000000000000000000000000000000000000", - reward: BigNumber.ZERO, + reward: 0n, timestamp: match.number, - totalAmount: BigNumber.make("12499999999999986"), - totalFee: BigNumber.ZERO, + totalAmount: 12499999999999986n, + totalFee: 0n, transactions: match.array, version: 1, }, @@ -360,10 +359,10 @@ describe<{ payloadHash: match.string, payloadLength: match.number, previousBlock: "0000000000000000000000000000000000000000000000000000000000000000", - reward: BigNumber.ZERO, + reward: 0n, timestamp: match.number, - totalAmount: BigNumber.make("119999999983"), - totalFee: BigNumber.ZERO, + totalAmount: 119999999983n, + totalFee: 0n, transactions: match.array, version: 1, }, diff --git a/packages/crypto-commit/test/fixtures/block.ts b/packages/crypto-commit/test/fixtures/block.ts index d2747f5fee..5a0f884e4a 100644 --- a/packages/crypto-commit/test/fixtures/block.ts +++ b/packages/crypto-commit/test/fixtures/block.ts @@ -1,7 +1,5 @@ import type { Contracts } from "@mainsail/contracts"; -import { BigNumber } from "@mainsail/utils"; - export const validatorMnemonic = "sudden head royal retire duck discover danger then basic rice wish left whip chronic enrich sun behind idea remind retire coyote select goddess exile"; diff --git a/packages/crypto-proposal/test/fixtures/block.ts b/packages/crypto-proposal/test/fixtures/block.ts index 85e1277b65..04d2892578 100644 --- a/packages/crypto-proposal/test/fixtures/block.ts +++ b/packages/crypto-proposal/test/fixtures/block.ts @@ -1,5 +1,4 @@ import type { Contracts } from "@mainsail/contracts"; -import { BigNumber } from "@mainsail/utils"; export const validatorMnemonic = "sudden head royal retire duck discover danger then basic rice wish left whip chronic enrich sun behind idea remind retire coyote select goddess exile"; @@ -33,7 +32,7 @@ export const tx1 = { gasPrice: 5_000_000_000, // hash: "65d43d2bed464b6bb1df8d6c0136316d3a3559569904fb16d5e3a8d71ebc2ebc", network: 10_000, - nonce: BigNumber.ZERO, + nonce: 0n, r: "921101a4583fb153ec00e501f3c2e2636114e1c8c58d2df8a19426cc066a6768", s: "22db4bce1e0ace485ce0838d178b4d5bcfa9f69b315a14c580d9b01e5c980bdd", // senderLegacyAddress: "DUQKzkR4BP5UcWayJMpRXtpEXuw4zPbWhe", @@ -41,7 +40,7 @@ export const tx1 = { to: "0xBe89811e15f611C1db12e59679b6F3DC1F430155", // transactionIndex: 0, v: 0, - value: BigNumber.ZERO, + value: 0n, }; export const tx1Serialized = @@ -54,7 +53,7 @@ export const tx2 = { gasPrice: 5_000_000_000, // hash: "7a74379424e07173c137dd89c29f497b35d8013815b03096b51e67f87c453574", network: 10_000, - nonce: BigNumber.ONE, + nonce: 1n, r: "6c9842bc78c2f68468cbf8a8f3fec0ae2679707ffb606a4b373dd01a02af55fc", s: "1a4c4d984d750678fb204ce8b7e97d860c974ac1a423f098dc4921acd2be0c7d", // senderLegacyAddress: "DQJTK7of6bPUfJEuL9gUV4qnUyq72eskKe", @@ -62,7 +61,7 @@ export const tx2 = { to: "0xBe89811e15f611C1db12e59679b6F3DC1F430155", // transactionIndex: 1, v: 0, - value: BigNumber.ZERO, + value: 0n, }; export const tx2Serialized = diff --git a/packages/crypto-transaction/source/signer.test.ts b/packages/crypto-transaction/source/signer.test.ts index 5b603f5dab..4d2274de02 100644 --- a/packages/crypto-transaction/source/signer.test.ts +++ b/packages/crypto-transaction/source/signer.test.ts @@ -1,6 +1,5 @@ import type { Contracts } from "@mainsail/contracts"; import { Identifiers } from "@mainsail/constants"; -import { BigNumber } from "@mainsail/utils"; import { TransactionBuilder } from "../source/builder.js"; import { Application } from "@mainsail/kernel"; @@ -33,7 +32,7 @@ describe<{ await builder .gasPrice(5 * 1e9) .recipientAddress("0xAe44ad925374b90B5f2A285461A70D6ba655EE28") - .value(BigNumber.make(1).toFixed()) + .value("1") .nonce("0") .signWithKeyPair(context.keyPair) ).build(); diff --git a/packages/crypto-validation/package.json b/packages/crypto-validation/package.json index 88dae147fb..de9e2fee9d 100644 --- a/packages/crypto-validation/package.json +++ b/packages/crypto-validation/package.json @@ -24,7 +24,6 @@ "@mainsail/constants": "workspace:*", "@mainsail/container": "workspace:*", "@mainsail/kernel": "workspace:*", - "@mainsail/utils": "workspace:*", "ajv": "8.18.0" }, "devDependencies": { diff --git a/packages/crypto-validation/source/keywords.test.ts b/packages/crypto-validation/source/keywords.test.ts index 31e7c34ab1..066ba72ed2 100644 --- a/packages/crypto-validation/source/keywords.test.ts +++ b/packages/crypto-validation/source/keywords.test.ts @@ -1,5 +1,4 @@ import { Identifiers } from "@mainsail/constants"; -import { BigNumber } from "@mainsail/utils"; import { ServiceProvider as ValidationServiceProvider } from "@mainsail/validation"; import { ServiceProvider as CryptoConfigServiceProvider } from "@mainsail/crypto-config"; import type { Contracts } from "@mainsail/contracts"; @@ -88,108 +87,6 @@ describe<{ assert.defined(context.validator.validate("test", {}).error); }); - it("keyword bignumber should be ok if only one possible value is allowed", (context) => { - const schema = { - $id: "test", - bignumber: { maximum: 100, minimum: 100 }, - }; - context.validator.addSchema(schema); - - assert.undefined(context.validator.validate("test", BigNumber.make(100)).error); - - assert.defined(context.validator.validate("test", 100).error); - assert.defined(context.validator.validate("test", "100").error); - assert.defined(context.validator.validate("test", BigNumber.make(99)).error); - assert.defined(context.validator.validate("test", BigNumber.make(101)).error); - assert.defined(context.validator.validate("test", null).error); - assert.defined(context.validator.validate("test", undefined).error); - assert.defined(context.validator.validate("test", {}).error); - }); - - it("keyword bignumber should be ok if above or equal minimum", (context) => { - const schema = { - $id: "test", - bignumber: { minimum: 20 }, - }; - context.validator.addSchema(schema); - - assert.undefined(context.validator.validate("test", BigNumber.make(25)).error); - assert.undefined(context.validator.validate("test", BigNumber.make(20)).error); - - assert.defined(context.validator.validate("test", BigNumber.make(19)).error); - }); - - it("keyword bignumber should be ok if below or equal maximum", (context) => { - const schema = { - $id: "test", - bignumber: { maximum: 20 }, - }; - context.validator.addSchema(schema); - - assert.undefined(context.validator.validate("test", BigNumber.make(19)).error); - assert.undefined(context.validator.validate("test", BigNumber.make(20)).error); - assert.undefined(context.validator.validate("test", BigNumber.make(0)).error); - - assert.defined(context.validator.validate("test", BigNumber.make(-1)).error); - assert.defined(context.validator.validate("test", BigNumber.make(21)).error); - }); - - it("keyword bignumber should not be ok for values bigger than the absolute maximum", (context) => { - const schema = { - $id: "test", - bignumber: {}, - }; - context.validator.addSchema(schema); - - assert.undefined(context.validator.validate("test", BigNumber.make(Number.MAX_SAFE_INTEGER)).error); - assert.undefined(context.validator.validate("test", BigNumber.make("9223372036854775808")).error); - assert.undefined(context.validator.validate("test", BigNumber.UINT256_MAX).error); - - assert.defined(context.validator.validate("test", BigNumber.UINT256_MAX.plus(1)).error); - }); - - it("keyword bignumber should not be ok for number and string", (context) => { - const schema = { - $id: "test", - bignumber: { maximum: 2000, minimum: 100, type: "number" }, - }; - context.validator.addSchema(schema); - - assert.defined(context.validator.validate("test", 120).error); - assert.defined(context.validator.validate("test", "120").error); - }); - - it("keyword bignumber should not accept garbage", (context) => { - const schema = { - $id: "test", - bignumber: {}, - }; - context.validator.addSchema(schema); - - assert.defined(context.validator.validate("test").error); - assert.defined(context.validator.validate("test", {}).error); - assert.defined(context.validator.validate("test", /d+/).error); - assert.defined(context.validator.validate("test", "").error); - assert.defined(context.validator.validate("test", "\u0000").error); - }); - - it("keyword bignumber should not modify parent", (context) => { - const schema = { - $id: "test", - properties: { - id: { type: "string" }, - amount: { bignumber: { minimum: 1 } }, - }, - type: "object", - }; - context.validator.addSchema(schema); - - const object: any = { id: "test", amount: BigNumber.make("12") }; - assert.true(object.amount instanceof BigNumber); - assert.undefined(context.validator.validate("test", object).error); - assert.true(object.amount instanceof BigNumber); - }); - it("keyword limitToRoundValidators - should be ok", (context) => { const schema = { $id: "test", diff --git a/packages/crypto-validation/source/keywords.ts b/packages/crypto-validation/source/keywords.ts index cda970b46b..4a12c43e62 100644 --- a/packages/crypto-validation/source/keywords.ts +++ b/packages/crypto-validation/source/keywords.ts @@ -1,8 +1,6 @@ import type { Contracts } from "@mainsail/contracts"; import type { FuncKeywordDefinition } from "ajv"; -import { BigNumber } from "@mainsail/utils"; - import { parseBlockNumber } from "./parse-block-number.js"; export const makeKeywords = ( @@ -10,7 +8,6 @@ export const makeKeywords = ( ): { maxBytes: FuncKeywordDefinition; bigInt: FuncKeywordDefinition; - bignumber: FuncKeywordDefinition; buffer: FuncKeywordDefinition; isValidatorIndex: FuncKeywordDefinition; limitToRoundValidators: FuncKeywordDefinition; @@ -26,36 +23,6 @@ export const makeKeywords = ( type: "string", }; - const bignumber: FuncKeywordDefinition = { - compile: (schema) => (data) => { - const minimum = schema.minimum !== undefined ? schema.minimum : 0; - const maximum = schema.maximum !== undefined ? schema.maximum : BigNumber.UINT256_MAX; - - if (!(data instanceof BigNumber)) { - return false; - } - - if (data.isLessThan(minimum)) { - return false; - } - - if (data.isGreaterThan(maximum)) { - return false; - } - - return true; - }, - errors: false, - keyword: "bignumber", - metaSchema: { - properties: { - maximum: { type: "integer" }, - minimum: { type: "integer" }, - }, - type: "object", - }, - }; - const bigInt: FuncKeywordDefinition = { compile: (schema) => (data) => { const minimum = schema.minimum !== undefined ? schema.minimum : 0n; @@ -155,5 +122,5 @@ export const makeKeywords = ( }, }; - return { bigInt, bignumber, buffer, isValidatorIndex, limitToRoundValidators, maxBytes }; + return { bigInt, buffer, isValidatorIndex, limitToRoundValidators, maxBytes }; }; diff --git a/packages/evm-consensus/source/deployer.ts b/packages/evm-consensus/source/deployer.ts index 9761883cd7..1cde2ae849 100644 --- a/packages/evm-consensus/source/deployer.ts +++ b/packages/evm-consensus/source/deployer.ts @@ -3,7 +3,7 @@ import type { Contracts } from "@mainsail/contracts"; import { Events, Identifiers } from "@mainsail/constants"; import { inject, injectable, tagged } from "@mainsail/container"; import { ConsensusAbi, ERC1967ProxyAbi, MultiPaymentAbi, UsernamesAbi } from "@mainsail/evm-contracts"; -import { assert, BigNumber } from "@mainsail/utils"; +import { assert } from "@mainsail/utils"; import { Address, encodeDeployData, encodeFunctionData, getCreateAddress, Hex, toBytes } from "viem"; import { Identifiers as EvmConsensusIdentifiers } from "./identifiers.js"; @@ -78,8 +78,8 @@ export class Deployer { const genesisInfo = { account: this.#genesisBlockInfo.generatorAddress, deployerAccount: this.deployerAddress, - initialBlockNumber: BigNumber.make(this.#genesisBlockInfo.initialBlockNumber).toBigInt(), - initialSupply: BigNumber.make(this.#genesisBlockInfo.initialSupply).toBigInt(), + initialBlockNumber: BigInt(this.#genesisBlockInfo.initialBlockNumber), + initialSupply: BigInt(this.#genesisBlockInfo.initialSupply), usernameContract: getCreateAddress({ from: this.deployerAddress, nonce: 3n }), // PROXY Uses nonce 3 validatorContract: getCreateAddress({ from: this.deployerAddress, nonce: 1n }), // PROXY Uses nonce 1 diff --git a/packages/evm-consensus/source/service-provider.ts b/packages/evm-consensus/source/service-provider.ts index fcb7b5f700..69a95aaec6 100644 --- a/packages/evm-consensus/source/service-provider.ts +++ b/packages/evm-consensus/source/service-provider.ts @@ -3,7 +3,7 @@ import type { Contracts } from "@mainsail/contracts"; import { Identifiers } from "@mainsail/constants"; import { injectable } from "@mainsail/container"; import { Providers } from "@mainsail/kernel"; -import { assert, BigNumber } from "@mainsail/utils"; +import { assert } from "@mainsail/utils"; import { Deployer } from "./deployer.js"; import { Identifiers as EvmConsensusIdentifiers } from "./identifiers.js"; @@ -38,10 +38,10 @@ export class ServiceProvider extends Providers.ServiceProvider { #calculateInitialSupply(genesisBlock: Contracts.Crypto.CommitJson): string { const generatorAddress = genesisBlock.block.proposer; - let supply = BigNumber.ZERO; + let supply = 0n; for (const transaction of genesisBlock.block.transactions.filter((tx) => tx.from === generatorAddress)) { - supply = supply.plus(transaction.value); + supply += BigInt(transaction.value); } return supply.toString(); diff --git a/packages/evm-consensus/source/services/consensus-contract-service.ts b/packages/evm-consensus/source/services/consensus-contract-service.ts index 4f0dd766ab..022cdd2731 100644 --- a/packages/evm-consensus/source/services/consensus-contract-service.ts +++ b/packages/evm-consensus/source/services/consensus-contract-service.ts @@ -3,7 +3,6 @@ import type { Contracts } from "@mainsail/contracts"; import { Identifiers } from "@mainsail/constants"; import { inject, injectable, tagged } from "@mainsail/container"; import { ConsensusAbi } from "@mainsail/evm-contracts"; -import { BigNumber } from "@mainsail/utils"; import { decodeFunctionResult, encodeFunctionData, toHex } from "viem"; import { Identifiers as EvmConsensusIdentifiers } from "../identifiers.js"; @@ -71,9 +70,9 @@ export class ConsensusContractService implements Contracts.Evm.ConsensusContract const validatorWallet: Contracts.State.ValidatorWallet = { address, blsPublicKey: blsPublicKey.slice(2), - fee: BigNumber.make(fee), + fee: fee, isResigned, - voteBalance: BigNumber.make(voteBalance), + voteBalance: voteBalance, votersCount: Number(votersCount), }; @@ -121,9 +120,9 @@ export class ConsensusContractService implements Contracts.Evm.ConsensusContract const validatorWallet: Contracts.State.ValidatorWallet = { address: address, blsPublicKey: blsPublicKey.slice(2), - fee: BigNumber.make(fee), + fee: fee, isResigned, - voteBalance: BigNumber.make(voteBalance), + voteBalance: voteBalance, votersCount: Number(votersCount), }; diff --git a/packages/evm-consensus/source/services/rounds-iterator.ts b/packages/evm-consensus/source/services/rounds-iterator.ts index 0468872ca8..befe2575cc 100644 --- a/packages/evm-consensus/source/services/rounds-iterator.ts +++ b/packages/evm-consensus/source/services/rounds-iterator.ts @@ -3,7 +3,6 @@ import type { Contracts } from "@mainsail/contracts"; import { Identifiers } from "@mainsail/constants"; import { inject, injectable, tagged } from "@mainsail/container"; import { ConsensusAbi } from "@mainsail/evm-contracts"; -import { BigNumber } from "@mainsail/utils"; import { decodeFunctionResult, encodeFunctionData, toHex } from "viem"; import { Identifiers as EvmConsensusIdentifiers } from "../identifiers.js"; @@ -98,7 +97,7 @@ export class AsyncValidatorRoundsIterator implements AsyncIterable { - const processResult = { feeUsed: BigNumber.ZERO, gasUsed: 0, receipts: new Map(), success: false }; + const processResult = { feeUsed: 0n, gasUsed: 0, receipts: new Map(), success: false }; try { await this.verifier.verify(unit); @@ -182,13 +182,13 @@ export class BlockProcessor implements Contracts.Processor.BlockProcessor { transaction: Contracts.Crypto.BlockTransaction, gasUsed: number, ): void { - const fee = this.feeCalculator.calculateConsumed(gasUsed, transaction.gasPrice); + const fee = this.feeCalculator.calculateConsumed(gasUsed, BigInt(transaction.gasPrice)); - if (processorResult.feeUsed.plus(fee).isGreaterThan(block.fee)) { + if (processorResult.feeUsed + fee > block.fee) { throw new Error("Cannot consume more fee"); } - processorResult.feeUsed = processorResult.feeUsed.plus(fee); + processorResult.feeUsed += fee; } #verifyConsumedAllGas( @@ -201,7 +201,7 @@ export class BlockProcessor implements Contracts.Processor.BlockProcessor { } #verifyTotalFee(block: Contracts.Crypto.Block, processorResult: Contracts.Processor.BlockProcessorResult): void { - if (!processorResult.feeUsed.isEqualTo(block.fee)) { + if (processorResult.feeUsed !== block.fee) { throw new Error(`Block fee ${block.fee} does not match consumed fee ${processorResult.feeUsed}`); } } @@ -261,7 +261,7 @@ export class BlockProcessor implements Contracts.Processor.BlockProcessor { const block = unit.getBlock(); await this.evm.updateRewardsAndVotes({ - blockReward: BigNumber.make(milestone.reward).toBigInt(), + blockReward: BigInt(milestone.reward), commitKey: { blockHash: block.hash, blockNumber: BigInt(block.number), @@ -288,7 +288,7 @@ export class BlockProcessor implements Contracts.Processor.BlockProcessor { blockNumber: BigInt(block.number), round: BigInt(block.round), }, - roundValidators: BigNumber.make(roundValidators).toBigInt(), + roundValidators: BigInt(roundValidators), specId: evmSpec, timestamp: BigInt(block.timestamp), validatorAddress: block.proposer, diff --git a/packages/processor/source/transaction-processor.ts b/packages/processor/source/transaction-processor.ts index b0fdd8545b..83d66368a4 100644 --- a/packages/processor/source/transaction-processor.ts +++ b/packages/processor/source/transaction-processor.ts @@ -58,7 +58,7 @@ export class TransactionProcessor implements Contracts.Processor.TransactionProc const receipt = await this.transactionHandler.apply(transactionHandlerContext, transaction); - const feeConsumed = this.feeCalculator.calculateConsumed(transaction.gasPrice, Number(receipt.gasUsed)); + const feeConsumed = this.feeCalculator.calculateConsumed(transaction.gasPrice, receipt.gasUsed); this.logger.debug( `executed EVM call (status=${receipt.status}, from=${transaction.from} to=${transaction.to} gasUsed=${receipt.gasUsed} paidNativeFee=${formatCurrency(this.configuration, feeConsumed)} deployed=${receipt.contractAddress ?? ""})`, "consensus", diff --git a/packages/serializer/source/serializer.test.ts b/packages/serializer/source/serializer.test.ts index 0c76e65438..f9aa2a33b0 100644 --- a/packages/serializer/source/serializer.test.ts +++ b/packages/serializer/source/serializer.test.ts @@ -12,7 +12,7 @@ import cryptoJson from "../../core/bin/config/devnet/core/crypto.json"; import { describe } from "@mainsail/test-runner"; import { Serializer } from "./serializer"; -import { BigNumber, ByteBuffer } from "@mainsail/utils"; +import { ByteBuffer } from "@mainsail/utils"; import { NotImplemented } from "@mainsail/exceptions"; describe<{ @@ -72,8 +72,8 @@ describe<{ uint32Value: 0x04050607, uint48Value: 0x010203040506, uint64Value: 123_456_789, - uint256Value: BigNumber.make("12345678901234567890"), - bigintValue: BigNumber.make("987654321"), + uint256Value: 12345678901234567890n, + bigintValue: 987654321n, hashValue: "11".repeat(32), shortHashValue: "22".repeat(4), diff --git a/packages/serializer/source/serializer.ts b/packages/serializer/source/serializer.ts index 2060a1b988..8f067fcb03 100644 --- a/packages/serializer/source/serializer.ts +++ b/packages/serializer/source/serializer.ts @@ -3,7 +3,7 @@ import type { Contracts } from "@mainsail/contracts"; import { Identifiers } from "@mainsail/constants"; import { inject, injectable, tagged } from "@mainsail/container"; import { NotImplemented } from "@mainsail/exceptions"; -import { assert, BigNumber, ByteBuffer, validatorSetPack, validatorSetUnpack } from "@mainsail/utils"; +import { assert, ByteBuffer, validatorSetPack, validatorSetUnpack } from "@mainsail/utils"; type TransactionCount = Pick; @@ -182,9 +182,7 @@ export class Serializer implements Contracts.Serializer.Serializer { } if (schema.type === "bigint") { - target[property] = this.#readOptional(schema, source, () => - BigNumber.make(source.readUint64().toString()), - ); + target[property] = this.#readOptional(schema, source, () => source.readUint64()); continue; } diff --git a/packages/snapshot-legacy-importer/source/importer.ts b/packages/snapshot-legacy-importer/source/importer.ts index 4d562a6d61..8e435864ad 100644 --- a/packages/snapshot-legacy-importer/source/importer.ts +++ b/packages/snapshot-legacy-importer/source/importer.ts @@ -5,7 +5,7 @@ import { inject, injectable, tagged } from "@mainsail/container"; import { Identifiers as EvmConsensusIdentifiers } from "@mainsail/evm-consensus"; import { ConsensusAbi, UsernamesAbi } from "@mainsail/evm-contracts"; import { Interfaces } from "@mainsail/snapshot-legacy-exporter"; -import { assert, BigNumber, chunk } from "@mainsail/utils"; +import { assert, chunk } from "@mainsail/utils"; import { entropyToMnemonic } from "bip39"; import { createHash } from "node:crypto"; import { promisify } from "node:util"; @@ -178,7 +178,7 @@ export class Importer implements Contracts.Snapshot.LegacyImporter { hash.update(JSON.stringify(wallet)); // the received balance is based on 8 decimals; convert it to WEI (18 decimals) - const balance = BigNumber.make(wallet.balance).times(1e10).toBigInt(); + const balance = BigInt(wallet.balance) * BigInt(1e10); if (balance < 0) { // skip OG genesis wallet @@ -203,7 +203,7 @@ export class Importer implements Contracts.Snapshot.LegacyImporter { balance, ethAddress, legacyAttributes: { - legacyNonce: BigNumber.make(wallet.legacyNonce).toBigInt(), + legacyNonce: BigInt(wallet.legacyNonce), multiSignature: wallet.attributes?.["multiSignature"]?.["publicKeys"] ? (wallet.attributes?.[ "multiSignature" diff --git a/packages/state/source/wallets/wallet.test.ts b/packages/state/source/wallets/wallet.test.ts index 6e1ecd756a..be53881063 100644 --- a/packages/state/source/wallets/wallet.test.ts +++ b/packages/state/source/wallets/wallet.test.ts @@ -1,4 +1,3 @@ -import { BigNumber } from "@mainsail/utils"; import { Identifiers } from "@mainsail/constants"; import { Application } from "@mainsail/kernel"; import { describe } from "@mainsail/test-runner"; @@ -47,69 +46,69 @@ describe<{ const wallet = await app.resolve(Wallet).init("Abcde"); - assert.equal(wallet.getBalance(), BigNumber.make(2)); - assert.equal(wallet.getNonce(), BigNumber.make(3)); + assert.equal(wallet.getBalance(), 2n); + assert.equal(wallet.getNonce(), 3n); }); it("should set and get balance", async ({ app }) => { const address = "Abcde"; const wallet = await app.resolve(Wallet).init(address); - assert.equal(wallet.getBalance(), BigNumber.ZERO); + assert.equal(wallet.getBalance(), 0n); - wallet.setBalance(BigNumber.ONE); - assert.equal(wallet.getBalance(), BigNumber.ONE); + wallet.setBalance(1n); + assert.equal(wallet.getBalance(), 1n); }); it("should set and get nonce", async ({ app }) => { const address = "Abcde"; const wallet = await app.resolve(Wallet).init(address); - assert.equal(wallet.getNonce(), BigNumber.ZERO); + assert.equal(wallet.getNonce(), 0n); - wallet.setNonce(BigNumber.ONE); - assert.equal(wallet.getNonce(), BigNumber.ONE); + wallet.setNonce(1n); + assert.equal(wallet.getNonce(), 1n); }); it("should increase balance", async ({ app }) => { const address = "Abcde"; const wallet = await app.resolve(Wallet).init(address); - assert.equal(wallet.getBalance(), BigNumber.ZERO); + assert.equal(wallet.getBalance(), 0n); - assert.equal(wallet.increaseBalance(BigNumber.ONE), wallet); - assert.equal(wallet.getBalance(), BigNumber.ONE); + assert.equal(wallet.increaseBalance(1n), wallet); + assert.equal(wallet.getBalance(), 1n); }); it("should decrease balance", async ({ app }) => { const address = "Abcde"; const wallet = await app.resolve(Wallet).init(address); - assert.equal(wallet.getBalance(), BigNumber.ZERO); + assert.equal(wallet.getBalance(), 0n); - assert.equal(wallet.decreaseBalance(BigNumber.ONE), wallet); - assert.equal(wallet.getBalance(), BigNumber.make("-1")); + assert.equal(wallet.decreaseBalance(1n), wallet); + assert.equal(wallet.getBalance(), -1n); }); it("should increase nonce", async ({ app }) => { const address = "Abcde"; const wallet = await app.resolve(Wallet).init(address); - assert.equal(wallet.getNonce(), BigNumber.ZERO); + assert.equal(wallet.getNonce(), 0n); wallet.increaseNonce(); - assert.equal(wallet.getNonce(), BigNumber.ONE); + assert.equal(wallet.getNonce(), 1n); }); it("should decrease nonce", async ({ app }) => { const address = "Abcde"; const wallet = await app.resolve(Wallet).init(address); - assert.equal(wallet.getNonce(), BigNumber.ZERO); + assert.equal(wallet.getNonce(), 0n); wallet.decreaseNonce(); - assert.equal(wallet.getNonce(), BigNumber.make("-1")); + assert.equal(wallet.getNonce(), -1n); }); it("#getLegacyAddress - should get address", async ({ app }) => { diff --git a/packages/state/source/wallets/wallet.ts b/packages/state/source/wallets/wallet.ts index 8914db2378..24b4c23c52 100644 --- a/packages/state/source/wallets/wallet.ts +++ b/packages/state/source/wallets/wallet.ts @@ -2,7 +2,7 @@ import type { Contracts } from "@mainsail/contracts"; import { Identifiers } from "@mainsail/constants"; import { inject, injectable, tagged } from "@mainsail/container"; -import { assert, BigNumber } from "@mainsail/utils"; +import { assert } from "@mainsail/utils"; @injectable() export class Wallet implements Contracts.State.Wallet { @@ -12,8 +12,8 @@ export class Wallet implements Contracts.State.Wallet { protected address!: string; protected legacyAddress: string | undefined; - protected balance = BigNumber.ZERO; - protected nonce = BigNumber.ZERO; + protected balance = 0n; + protected nonce = 0n; protected legacyAttributes: Contracts.Evm.LegacyAttributes = {}; @@ -22,8 +22,8 @@ export class Wallet implements Contracts.State.Wallet { this.legacyAddress = legacyAddress; const accountInfo = await this.evm.getAccountInfoExtended(address, legacyAddress); - this.balance = BigNumber.make(accountInfo.balance); - this.nonce = BigNumber.make(accountInfo.nonce); + this.balance = accountInfo.balance; + this.nonce = accountInfo.nonce; this.legacyAttributes = accountInfo.legacyAttributes; return this; @@ -33,40 +33,40 @@ export class Wallet implements Contracts.State.Wallet { return this.address; } - public getBalance(): BigNumber { + public getBalance(): bigint { return this.balance; } - public setBalance(balance: BigNumber): void { + public setBalance(balance: bigint): void { this.balance = balance; } - public getNonce(): BigNumber { + public getNonce(): bigint { return this.nonce; } - public setNonce(nonce: BigNumber): void { + public setNonce(nonce: bigint): void { this.nonce = nonce; } - public increaseBalance(balance: BigNumber): Contracts.State.Wallet { - this.setBalance(this.getBalance().plus(balance)); + public increaseBalance(balance: bigint): Contracts.State.Wallet { + this.setBalance(this.getBalance() + balance); return this; } - public decreaseBalance(balance: BigNumber): Contracts.State.Wallet { - this.setBalance(this.getBalance().minus(balance)); + public decreaseBalance(balance: bigint): Contracts.State.Wallet { + this.setBalance(this.getBalance() - balance); return this; } public increaseNonce(): void { - this.setNonce(this.getNonce().plus(BigNumber.ONE)); + this.setNonce(this.getNonce() + 1n); } public decreaseNonce(): void { - this.setNonce(this.getNonce().minus(BigNumber.ONE)); + this.setNonce(this.getNonce() - 1n); } // Legacy diff --git a/packages/test-factories/source/factories/factories/block.test.ts b/packages/test-factories/source/factories/factories/block.test.ts index 93e8c8e35c..9c703ecf6b 100644 --- a/packages/test-factories/source/factories/factories/block.test.ts +++ b/packages/test-factories/source/factories/factories/block.test.ts @@ -1,5 +1,4 @@ import type { Contracts } from "@mainsail/contracts"; -import { BigNumber } from "@mainsail/utils"; import { Application } from "@mainsail/kernel"; import cryptoConfig from "../../../../core/bin/config/devnet/core/crypto.json"; import { describe } from "@mainsail/test-runner"; diff --git a/packages/test-factories/source/factories/factories/block.ts b/packages/test-factories/source/factories/factories/block.ts index 7cfff7bb99..684e2a391e 100644 --- a/packages/test-factories/source/factories/factories/block.ts +++ b/packages/test-factories/source/factories/factories/block.ts @@ -1,7 +1,7 @@ import type { Contracts } from "@mainsail/contracts"; import { Identifiers } from "@mainsail/constants"; -import { assert, BigNumber } from "@mainsail/utils"; +import { assert } from "@mainsail/utils"; import dayjs from "dayjs"; import type { FactoryBuilder } from "../factory-builder.js"; @@ -62,8 +62,8 @@ export const registerBlockFactory = async ( } } - const totals: { gasPrice: BigNumber; gasUsed: number } = { - gasPrice: BigNumber.ZERO, + const totals: { gasPrice: bigint; gasUsed: number } = { + gasPrice: 0n, gasUsed: 0, }; const payloadBuffers: Buffer[] = []; @@ -73,7 +73,7 @@ export const registerBlockFactory = async ( for (const transaction of transactions) { assert.string(transaction.hash); - totals.gasPrice = totals.gasPrice.plus(transaction.gasPrice); + totals.gasPrice += BigInt(transaction.gasPrice); // TODO: calculate actual gas used totals.gasUsed += transaction.gasLimit; @@ -87,7 +87,7 @@ export const registerBlockFactory = async ( const commit = { block: await app.get(Identifiers.Cryptography.Block.Factory).make( { - fee: totals.gasPrice.toBigInt(), + fee: totals.gasPrice, gasUsed: totals.gasUsed, logsBloom: "0".repeat(512), number: previousBlock.number + 1, diff --git a/packages/test-factories/source/factories/factories/transaction.ts b/packages/test-factories/source/factories/factories/transaction.ts index 975faae656..6ad0426f7c 100644 --- a/packages/test-factories/source/factories/factories/transaction.ts +++ b/packages/test-factories/source/factories/factories/transaction.ts @@ -2,7 +2,6 @@ import type { Contracts } from "@mainsail/contracts"; import { Identifiers } from "@mainsail/constants"; import { TransactionBuilder } from "@mainsail/crypto-transaction"; -import { BigNumber } from "@mainsail/utils"; import type { FactoryBuilder } from "../factory-builder.js"; import type { EvmCallOptions, TransactionOptions, TransferOptions } from "../types.js"; @@ -50,7 +49,7 @@ export const registerTransferFactory = (factory: FactoryBuilder, app: Contracts. return applyModifiers( transferBuilder - .value(BigNumber.make(options.amount || AMOUNT).toFixed()) + .value(BigInt(options.amount || AMOUNT).toString()) .recipientAddress( options.recipientAddress || (await app diff --git a/packages/test-factories/source/internal/signer.ts b/packages/test-factories/source/internal/signer.ts index e60a32f52d..6efa5140f5 100644 --- a/packages/test-factories/source/internal/signer.ts +++ b/packages/test-factories/source/internal/signer.ts @@ -1,7 +1,6 @@ import type { Contracts } from "@mainsail/contracts"; import { type TransactionBuilder } from "@mainsail/crypto-transaction"; -import { BigNumber } from "@mainsail/utils"; import type { EvmCallOptions, TransferOptions } from "../factories/types.js"; @@ -10,14 +9,14 @@ import { FactoryBuilder } from "../factories/factory-builder.js"; export class Signer { #config: Contracts.Crypto.NetworkConfig; - #nonce: BigNumber; + #nonce: bigint; #factoryBuilder: FactoryBuilder; #initialized = false; public constructor(config: Contracts.Crypto.NetworkConfig, nonce: string) { this.#config = config; - this.#nonce = BigNumber.make(nonce || 0); + this.#nonce = BigInt(nonce || 0); this.#factoryBuilder = new FactoryBuilder(); } @@ -25,7 +24,7 @@ export class Signer { public async makeTransfer(options: TransferOptions): Promise { await this.#initialize(); - options = { ...options, nonce: this.#nonce.toFixed() }; + options = { ...options, nonce: this.#nonce.toString() }; const states = ["sign"]; @@ -42,7 +41,7 @@ export class Signer { public async makeEvmCall(options: EvmCallOptions): Promise { await this.#initialize(); - options = { nonce: this.#nonce.toFixed(), ...options }; + options = { nonce: this.#nonce.toString(), ...options }; const builder = await this.#factoryBuilder .get("EvmCall") @@ -55,7 +54,7 @@ export class Signer { } #incrementNonce(): void { - this.#nonce = this.#nonce.plus(1); + this.#nonce += 1n; } async #initialize() { diff --git a/packages/test-transaction-builders/source/types.ts b/packages/test-transaction-builders/source/types.ts index d9b78fff16..b12320b3be 100644 --- a/packages/test-transaction-builders/source/types.ts +++ b/packages/test-transaction-builders/source/types.ts @@ -1,12 +1,11 @@ import type { Contracts } from "@mainsail/contracts"; -import type { BigNumber } from "@mainsail/utils"; export interface Context { app: Contracts.Kernel.Application; wallets: Contracts.Crypto.KeyPair[]; fundedWalletProvider?: ( context: { app: Contracts.Kernel.Application; wallets: Contracts.Crypto.KeyPair[] }, - amount?: BigNumber, + amount?: bigint, ) => Promise; } @@ -24,7 +23,7 @@ export interface TransactionOptions { export interface TransferOptions extends TransactionOptions { recipient?: string; - amount?: number | string | BigNumber; + amount?: number | string | bigint; } export interface EvmCallOptions extends TransactionOptions { diff --git a/packages/test-transaction-builders/source/utilities.ts b/packages/test-transaction-builders/source/utilities.ts index 27758834c7..84c6e68204 100644 --- a/packages/test-transaction-builders/source/utilities.ts +++ b/packages/test-transaction-builders/source/utilities.ts @@ -2,7 +2,7 @@ import type { Contracts } from "@mainsail/contracts"; import { Identifiers } from "@mainsail/constants"; import { TransactionBuilder, TransactionFactory, Verifier } from "@mainsail/crypto-transaction"; -import { BigNumber, sleep } from "@mainsail/utils"; +import { sleep } from "@mainsail/utils"; import { randomBytes } from "crypto"; import type { Context, TransactionOptions } from "./types.js"; @@ -56,7 +56,7 @@ const applyCustomSignatures = async ( // transaction.serialized = Buffer.from(transactionHex, "hex"); }; -export const getNonceByPublicKey = async (app: Contracts.Kernel.Application, publicKey: string): Promise => { +export const getNonceByPublicKey = async (app: Contracts.Kernel.Application, publicKey: string): Promise => { const address = await app .get(Identifiers.Cryptography.Identity.Address.Factory) .fromPublicKey(publicKey); @@ -64,7 +64,7 @@ export const getNonceByPublicKey = async (app: Contracts.Kernel.Application, pub const instance = app.getTagged(Identifiers.Evm.Instance, "instance", "evm"); const accountInfo = await instance.getAccountInfo(address); - return BigNumber.make(accountInfo.nonce); + return accountInfo.nonce; }; export const buildSignedTransaction = async ( @@ -104,7 +104,7 @@ export const buildSignedTransaction = async => { +export const getRandomFundedWallet = async (context: Context, amount?: bigint): Promise => { if (context.fundedWalletProvider) { return context.fundedWalletProvider(context, amount); } @@ -197,7 +194,7 @@ export const getRandomFundedWallet = async ( const recipient = await app .get(Identifiers.Cryptography.Identity.Address.Factory) .fromPublicKey(randomKeyPair.publicKey); - amount = amount ?? BigNumber.make("1000000000000000000"); + amount = amount ?? BigInt("1000000000000000000"); const nonce = await getNonceByPublicKey(app, wallets[0].publicKey); @@ -206,8 +203,8 @@ export const getRandomFundedWallet = async ( .resolve(TransactionBuilder) .gasPrice(5) .recipientAddress(recipient) - .value(BigNumber.make(amount).toFixed()) - .nonce(nonce.plus(1).toFixed()) + .value(amount.toString()) + .nonce((nonce + 1n).toString()) .signWithKeyPair(wallets[0]) ).build(); diff --git a/packages/transaction-pool-service/source/errors.test.ts b/packages/transaction-pool-service/source/errors.test.ts index fb755ec68d..8d51df5597 100644 --- a/packages/transaction-pool-service/source/errors.test.ts +++ b/packages/transaction-pool-service/source/errors.test.ts @@ -1,6 +1,4 @@ import * as Exceptions from "@mainsail/exceptions"; -import { BigNumber } from "@mainsail/utils"; - import { describe } from "@mainsail/test-runner"; describe<{ @@ -8,11 +6,11 @@ describe<{ }>("Errors", ({ it, assert, beforeAll }) => { beforeAll((context) => { context.transaction = { - amount: BigNumber.make(100), + amount: 100n, gasPrice: 900 * 1e9, hash: "dummy-tx-id", network: 30, - nonce: BigNumber.make(1), + nonce: 1n, from: "dummy-sender-key", type: 0, hash: "dummy-tx-id", @@ -55,7 +53,7 @@ describe<{ }); it("TransactionPoolFullError", (context) => { - const error = new Exceptions.TransactionPoolFullError(context.transaction, new BigNumber(1000 * 1e9)); + const error = new Exceptions.TransactionPoolFullError(context.transaction, 1000 * 1e9); assert.instance(error, Exceptions.PoolError); assert.equal(error.type, "ERR_POOL_FULL"); diff --git a/packages/transaction-pool-service/source/mempool.ts b/packages/transaction-pool-service/source/mempool.ts index 597839f976..4ff0c6ff2d 100644 --- a/packages/transaction-pool-service/source/mempool.ts +++ b/packages/transaction-pool-service/source/mempool.ts @@ -51,7 +51,7 @@ export class Mempool implements Contracts.TransactionPool.Mempool { try { // When receiving a nonce less than or equal to the current nonce try to replace it. - if (transaction.nonce <= senderMempool.getNonce().toBigInt()) { + if (transaction.nonce <= senderMempool.getNonce()) { await this.#tryReplaceTransaction(transaction, senderMempool); } else { await senderMempool.addTransaction(transaction); diff --git a/packages/transaction-pool-service/source/processor.test.ts b/packages/transaction-pool-service/source/processor.test.ts index f97171ea87..8c88c3041b 100644 --- a/packages/transaction-pool-service/source/processor.test.ts +++ b/packages/transaction-pool-service/source/processor.test.ts @@ -2,7 +2,6 @@ import { Container } from "@mainsail/container"; import { Identifiers } from "@mainsail/constants"; import * as Exceptions from "@mainsail/exceptions"; import { Configuration } from "@mainsail/crypto-config"; -import { BigNumber } from "@mainsail/utils"; import crypto from "../../core/bin/config/devnet/core/crypto.json"; import { describe } from "@mainsail/test-runner"; @@ -58,9 +57,9 @@ describe<{ context.transaction1 = { data: { - amount: BigNumber.make(100), + amount: 100n, id: "dummy-tx-id", - nonce: BigNumber.make(1), + nonce: 1n, senderPublicKey: "dummy-sender-key", type: 0, version: 2, @@ -73,9 +72,9 @@ describe<{ context.transaction2 = { data: { - amount: BigNumber.make(100), + amount: 100n, id: "dummy-tx-id-2", - nonce: BigNumber.make(1), + nonce: 1n, senderPublicKey: "dummy-sender-key", type: 0, typeGroup: undefined, diff --git a/packages/transaction-pool-service/source/query.test.ts b/packages/transaction-pool-service/source/query.test.ts index c86779122b..0c099bf2a1 100644 --- a/packages/transaction-pool-service/source/query.test.ts +++ b/packages/transaction-pool-service/source/query.test.ts @@ -2,7 +2,6 @@ import { Container } from "@mainsail/container"; import { Identifiers } from "@mainsail/constants"; import { describe } from "@mainsail/test-runner"; -import { BigNumber } from "@mainsail/utils"; import { Query, QueryIterable } from "."; describe<{ @@ -26,36 +25,36 @@ describe<{ beforeEach((context) => { context.sender1Transaction100 = { - amount: BigNumber.make(100), + amount: 100n, gasPrice: 100 * 1e9, - nonce: BigNumber.make(1), + nonce: 1n, from: "sender1", hash: "dummy-tx-id", serialized: Buffer.from("dummy"), }; context.sender1Transaction200 = { - amount: BigNumber.make(100), + amount: 100n, gasPrice: 200 * 1e9, - nonce: BigNumber.make(2), + nonce: 2n, from: "sender1", hash: "dummy-tx-id-2", serialized: Buffer.from("dummy-2"), }; context.sender2Transaction100 = { - amount: BigNumber.make(100), + amount: 100n, gasPrice: 300 * 1e9, - nonce: BigNumber.make(3), + nonce: 3n, from: "sender2", hash: "dummy-tx-id-3", serialized: Buffer.from("dummy-3"), }; context.sender2Transaction200 = { - amount: BigNumber.make(100), + amount: 100n, gasPrice: 400 * 1e9, - nonce: BigNumber.make(4), + nonce: 4n, from: "sender2", hash: "dummy-tx-id-4", serialized: Buffer.from("dummy-4"), diff --git a/packages/transaction-pool-service/source/sender-mempool.test.ts b/packages/transaction-pool-service/source/sender-mempool.test.ts index d72af118da..1800f5bc0c 100644 --- a/packages/transaction-pool-service/source/sender-mempool.test.ts +++ b/packages/transaction-pool-service/source/sender-mempool.test.ts @@ -4,7 +4,6 @@ import { Identifiers } from "@mainsail/constants"; import * as Exceptions from "@mainsail/exceptions"; import { describeSkip } from "@mainsail/test-runner"; -import { BigNumber } from "../../utils/source/big-number"; import { SenderMempool } from "."; describeSkip<{ @@ -30,9 +29,9 @@ describeSkip<{ const tx1 = { data: { - amount: BigNumber.make(100), - fee: BigNumber.make(900), - nonce: BigNumber.make(1), + amount: 100n, + fee: 900n, + nonce: 1n, senderPublicKey: "dummy-sender-key", type: 1, }, @@ -45,9 +44,9 @@ describeSkip<{ const tx2 = { data: { - amount: BigNumber.make(100), - fee: BigNumber.make(900), - nonce: BigNumber.make(2), + amount: 100n, + fee: 900n, + nonce: 2n, senderPublicKey: "dummy-sender-key", type: 1, }, @@ -60,9 +59,9 @@ describeSkip<{ const tx3 = { data: { - amount: BigNumber.make(100), - fee: BigNumber.make(900), - nonce: BigNumber.make(3), + amount: 100n, + fee: 900n, + nonce: 3n, senderPublicKey: "dummy-sender-key", type: 1, }, diff --git a/packages/transaction-pool-service/source/sender-mempool.ts b/packages/transaction-pool-service/source/sender-mempool.ts index 646a6d059c..0ef3718bc6 100644 --- a/packages/transaction-pool-service/source/sender-mempool.ts +++ b/packages/transaction-pool-service/source/sender-mempool.ts @@ -3,7 +3,7 @@ import type { Contracts } from "@mainsail/contracts"; import { Identifiers } from "@mainsail/constants"; import { inject, injectable, tagged } from "@mainsail/container"; import { SenderExceededMaximumTransactionCountError } from "@mainsail/exceptions"; -import { assert, BigNumber, Lock } from "@mainsail/utils"; +import { assert, Lock } from "@mainsail/utils"; @injectable() export class SenderMempool implements Contracts.TransactionPool.SenderMempool { @@ -41,7 +41,7 @@ export class SenderMempool implements Contracts.TransactionPool.SenderMempool { return [...this.#transactions].reverse(); } - public getNonce(): BigNumber { + public getNonce(): bigint { return this.senderState.getNonce(); } diff --git a/packages/transaction-pool-service/source/sender-state.ts b/packages/transaction-pool-service/source/sender-state.ts index 043d555be2..0cc18aa879 100644 --- a/packages/transaction-pool-service/source/sender-state.ts +++ b/packages/transaction-pool-service/source/sender-state.ts @@ -12,7 +12,6 @@ import { } from "@mainsail/exceptions"; import { Services } from "@mainsail/kernel"; import { Wallets } from "@mainsail/state"; -import { BigNumber } from "@mainsail/utils"; @injectable() export class SenderState implements Contracts.TransactionPool.SenderState { @@ -46,7 +45,7 @@ export class SenderState implements Contracts.TransactionPool.SenderState { return this; } - public getNonce(): BigNumber { + public getNonce(): bigint { return this.#wallet.getNonce(); } @@ -60,33 +59,27 @@ export class SenderState implements Contracts.TransactionPool.SenderState { await this.#validateTransaction(transaction); this.#wallet.increaseNonce(); - this.#wallet.decreaseBalance( - BigNumber.make(transaction.value + this.feeCalculator.calculate(transaction).toBigInt()), - ); + this.#wallet.decreaseBalance(transaction.value + this.feeCalculator.calculate(transaction)); } public async replace( oldTransaction: Contracts.Crypto.Transaction, newTransaction: Contracts.Crypto.Transaction, - currentNonce: BigNumber, + currentNonce: bigint, ): Promise { if (oldTransaction.nonce !== newTransaction.nonce) { throw new Error("cannot replace transaction with mismatching nonce"); } - const oldTransactionCost = BigNumber.make( - oldTransaction.value + this.feeCalculator.calculate(oldTransaction).toBigInt(), - ); - const newTransactionCost = BigNumber.make( - newTransaction.value + this.feeCalculator.calculate(newTransaction).toBigInt(), - ); + const oldTransactionCost = oldTransaction.value + this.feeCalculator.calculate(oldTransaction); + const newTransactionCost = newTransaction.value + this.feeCalculator.calculate(newTransaction); - const availableBalance = this.#wallet.getBalance().plus(oldTransactionCost); - if (availableBalance.isLessThan(newTransactionCost)) { + const availableBalance = this.#wallet.getBalance() + oldTransactionCost; + if (availableBalance < newTransactionCost) { return false; } - const nonceOffset = currentNonce.minus(newTransaction.nonce).times(-1); + const nonceOffset = (currentNonce - newTransaction.nonce) * -1n; await this.#validateTransaction(newTransaction, nonceOffset, oldTransactionCost); // Nonce stays the same @@ -99,15 +92,13 @@ export class SenderState implements Contracts.TransactionPool.SenderState { public revert(transaction: Contracts.Crypto.Transaction): void { this.#wallet.decreaseNonce(); - this.#wallet.increaseBalance( - BigNumber.make(transaction.value + this.feeCalculator.calculate(transaction).toBigInt()), - ); + this.#wallet.increaseBalance(transaction.value + this.feeCalculator.calculate(transaction)); } async #validateTransaction( transaction: Contracts.Crypto.Transaction, - nonceOffset: BigNumber = BigNumber.ZERO, - refund: BigNumber = BigNumber.ZERO, + nonceOffset: bigint = 0n, + refund: bigint = 0n, ): Promise { const maxTransactionBytes: number = this.configuration.getRequired("maxTransactionBytes"); if (transaction.serialized.length > maxTransactionBytes) { @@ -119,18 +110,11 @@ export class SenderState implements Contracts.TransactionPool.SenderState { throw new TransactionFromWrongNetworkError(transaction, chainId); } - if (!this.#wallet.getNonce().plus(nonceOffset).isEqualTo(transaction.nonce)) { - throw new UnexpectedNonceError(BigNumber.make(transaction.nonce), this.#wallet); + if (this.#wallet.getNonce() + nonceOffset !== transaction.nonce) { + throw new UnexpectedNonceError(transaction.nonce, this.#wallet); } - if ( - this.#wallet - .getBalance() - .plus(refund) - .minus(transaction.value) - .minus(this.feeCalculator.calculate(transaction)) - .isNegative() - ) { + if (this.#wallet.getBalance() + refund - transaction.value - this.feeCalculator.calculate(transaction) < 0n) { throw new InsufficientBalanceError(); } diff --git a/packages/transaction-pool-service/source/service.ts b/packages/transaction-pool-service/source/service.ts index 6ab9fc21eb..09737ab81d 100644 --- a/packages/transaction-pool-service/source/service.ts +++ b/packages/transaction-pool-service/source/service.ts @@ -3,7 +3,7 @@ import type { Contracts } from "@mainsail/contracts"; import { EnvironmentVariables, Events, Identifiers } from "@mainsail/constants"; import { inject, injectable, tagged } from "@mainsail/container"; import { PoolError, TransactionAlreadyInPoolError, TransactionPoolFullError } from "@mainsail/exceptions"; -import { BigNumber, Lock, randomNumber } from "@mainsail/utils"; +import { Lock, randomNumber } from "@mainsail/utils"; @injectable() export class Service implements Contracts.TransactionPool.Service { @@ -248,7 +248,7 @@ export class Service implements Contracts.TransactionPool.Service { if (this.getPoolSize() >= maxTransactionsInPool) { const lowest = await this.poolQuery.getFromLowestPriority().first(); - if (BigNumber.make(transaction.gasPrice).isLessThanEqual(lowest.gasPrice)) { + if (transaction.gasPrice <= lowest.gasPrice) { throw new TransactionPoolFullError(transaction, lowest.gasPrice); } diff --git a/packages/utils/source/big-number.test.ts b/packages/utils/source/big-number.test.ts deleted file mode 100644 index 7961cf5927..0000000000 --- a/packages/utils/source/big-number.test.ts +++ /dev/null @@ -1,92 +0,0 @@ -import BigNum from "bignumber.js"; - -import { describe } from "@mainsail/test-runner"; -import { BigNumber } from "./big-number"; - -describe("#BigNumber", ({ it, assert }) => { - it("should be created from hex", () => { - assert.equal(new BigNumber("0x20").toFixed(), new BigNum("0x20", 16).toFixed()); - }); - - it("should work with a BigNumber instance as input", () => { - assert.equal(new BigNumber(1e8).plus(new BigNumber(1e8)).toFixed(), new BigNum(1e8).plus(1e8).toFixed()); - }); - - it(".make", () => { - assert.equal(BigNumber.make(1e8).plus(1e8).toFixed(), new BigNum(1e8).plus(1e8).toFixed()); - }); - - it(".plus", () => { - assert.equal(new BigNumber(1e8).plus(1e8).toFixed(), new BigNum(1e8).plus(1e8).toFixed()); - }); - - it(".minus", () => { - assert.equal(new BigNumber(1e8).minus(1e8).toFixed(), new BigNum(1e8).minus(1e8).toFixed()); - }); - - it(".times", () => { - assert.equal(new BigNumber(1e8).times(1e8).toFixed(), new BigNum(1e8).times(1e8).toFixed()); - }); - - it(".dividedBy", () => { - assert.equal(new BigNumber(1e8).dividedBy(1e8).toFixed(), new BigNum(1e8).dividedBy(1e8).toFixed()); - }); - - it(".div", () => { - assert.equal(new BigNumber(1e8).div(1e8).toFixed(), new BigNum(1e8).div(1e8).toFixed()); - }); - - it(".isZero", () => { - assert.true(new BigNumber(0).isZero()); - }); - - it(".comparedTo", () => { - assert.equal(new BigNumber(5).comparedTo(5), 0); - assert.equal(new BigNumber(0).comparedTo(5), -1); - assert.equal(new BigNumber(5).comparedTo(0), 1); - }); - - it(".isLessThan", () => { - assert.true(new BigNumber(5).isLessThan(10)); - }); - - it(".isLessThanEqual", () => { - assert.true(new BigNumber(5).isLessThanEqual(10)); - assert.true(new BigNumber(5).isLessThanEqual(5)); - }); - - it(".isGreaterThan", () => { - assert.true(new BigNumber(10).isGreaterThan(5)); - }); - - it(".isGreaterThanEqual", () => { - assert.true(new BigNumber(10).isGreaterThanEqual(10)); - assert.true(new BigNumber(10).isGreaterThanEqual(5)); - }); - - it(".isEqualTo", () => { - assert.true(new BigNumber(10).isEqualTo(10)); - }); - - it(".isNegative", () => { - assert.true(new BigNumber(-10).isNegative()); - }); - - it(".toFixed", () => { - assert.equal(new BigNumber(1e8).toFixed(), `${1e8}`); - }); - - it(".toString", () => { - assert.equal(new BigNumber(1e8).toString(), `${1e8}`); - assert.equal(new BigNumber(255).toString(16), `ff`); - }); - - it(".toJSON", () => { - assert.equal(new BigNumber(1e8).toJSON(), `${1e8}`); - }); - - it(".toBigInt", () => { - assert.equal(new BigNumber(1e8).toBigInt(), BigInt(1e8)); - assert.equal(new BigNumber(255).toBigInt(), BigInt(255)); - }); -}); diff --git a/packages/utils/source/big-number.ts b/packages/utils/source/big-number.ts deleted file mode 100644 index d405f17f6c..0000000000 --- a/packages/utils/source/big-number.ts +++ /dev/null @@ -1,104 +0,0 @@ -export type BigNumberType = bigint | number | string | BigNumber; - -export class BigNumber { - public static readonly ZERO: BigNumber = new BigNumber(0); - public static readonly ONE: BigNumber = new BigNumber(1); - public static readonly WEI: BigNumber = new BigNumber(1e18); - public static readonly UINT256_MAX = new BigNumber(2n ** 256n - 1n); - - private readonly value: bigint; - - public constructor(value: BigNumberType) { - this.value = this.toBigNumber(value); - } - - public static make(value: BigNumberType): BigNumber { - return new BigNumber(value); - } - - public plus(other: BigNumberType): BigNumber { - return new BigNumber(this.value + this.toBigNumber(other)); - } - - public minus(other: BigNumberType): BigNumber { - return new BigNumber(this.value - this.toBigNumber(other)); - } - - public times(other: BigNumberType): BigNumber { - return new BigNumber(this.value * this.toBigNumber(other)); - } - - public dividedBy(other: BigNumberType): BigNumber { - return new BigNumber(this.value / this.toBigNumber(other)); - } - - public div(other: BigNumberType): BigNumber { - return this.dividedBy(other); - } - - public isZero(): boolean { - return this.value === BigInt(0); - } - - public comparedTo(other: BigNumberType): number { - const b = this.toBigNumber(other); - - if (this.value > b) { - return 1; - } - - if (this.value < b) { - return -1; - } - - return 0; - } - - public isLessThan(other: BigNumberType): boolean { - return this.value < this.toBigNumber(other); - } - - public isLessThanEqual(other: BigNumberType): boolean { - return this.value <= this.toBigNumber(other); - } - - public isGreaterThan(other: BigNumberType): boolean { - return this.value > this.toBigNumber(other); - } - - public isGreaterThanEqual(other: BigNumberType): boolean { - return this.value >= this.toBigNumber(other); - } - - public isEqualTo(other: BigNumberType): boolean { - return this.value === this.toBigNumber(other); - } - - public isNegative(): boolean { - return this.value < 0; - } - - public toFixed(): string { - return this.value.toString(); - } - - public toString(base: number = 10): string { - return this.value.toString(base); - } - - public toJSON(): string { - return this.toFixed(); - } - - public toBigInt(): bigint { - return this.value; - } - - private toBigNumber(value: BigNumberType): bigint { - if (value instanceof BigNumber) { - value = value.value; - } - - return BigInt(value); - } -} diff --git a/packages/utils/source/index.ts b/packages/utils/source/index.ts index 67f6b62062..df16c62673 100644 --- a/packages/utils/source/index.ts +++ b/packages/utils/source/index.ts @@ -2,7 +2,6 @@ export * from "./assert.js"; export * from "./assign.js"; export * from "./at.js"; export * from "./base64.js"; -export * from "./big-number.js"; export * from "./binary.js"; export * from "./byte-buffer.js"; export * from "./camel-case.js"; diff --git a/packages/validator/source/validator.ts b/packages/validator/source/validator.ts index 27ad838705..558412784b 100644 --- a/packages/validator/source/validator.ts +++ b/packages/validator/source/validator.ts @@ -3,7 +3,7 @@ import type { Contracts } from "@mainsail/contracts"; import { Enums, Identifiers } from "@mainsail/constants"; import { inject, injectable, tagged } from "@mainsail/container"; import { Identifiers as EvmConsensusIdentifiers } from "@mainsail/evm-consensus"; -import { assert, BigNumber } from "@mainsail/utils"; +import { assert } from "@mainsail/utils"; import { performance } from "perf_hooks"; @injectable() @@ -82,16 +82,7 @@ export class Validator implements Contracts.Validator.Validator { round: BigInt(round), }, ); - return this.#makeBlock( - round, - generatorAddress, - logsBloom, - stateRoot, - transactions, - timestamp, - gasUsed, - fee.toBigInt(), - ); + return this.#makeBlock(round, generatorAddress, logsBloom, stateRoot, transactions, timestamp, gasUsed, fee); } public async propose( @@ -158,7 +149,7 @@ export class Validator implements Contracts.Validator.Validator { stateRoot: string; transactions: Contracts.Crypto.Transaction[]; gasUsed: number; - fee: BigNumber; + fee: bigint; }> { const transactionBytes = await this.txPoolWorker.getTransactionBytes(); @@ -176,7 +167,7 @@ export class Validator implements Contracts.Validator.Validator { const milestone = this.cryptoConfiguration.getMilestone(); let gasLeft = milestone.block.maxGasLimit; let gasUsed = 0; - let fee = BigNumber.ZERO; + let fee = 0n; // txCollatorFactor% of the time for block preparation, the rest is for block and proposal serialization and signing const timeLimit = @@ -237,9 +228,7 @@ export class Validator implements Contracts.Validator.Validator { } gasUsed += Number(result.gasUsed); - fee = fee.plus( - this.gasFeeCalculator.calculateConsumed(transaction.gasPrice, Number(result.gasUsed)), - ); + fee += this.gasFeeCalculator.calculateConsumed(transaction.gasPrice, result.gasUsed); candidateTransactions.push(transaction); } catch (error) { this.logger.warn( @@ -253,7 +242,7 @@ export class Validator implements Contracts.Validator.Validator { } await evm.updateRewardsAndVotes({ - blockReward: BigNumber.make(milestone.reward).toBigInt(), + blockReward: BigInt(milestone.reward), commitKey, specId: milestone.evmSpec, timestamp: BigInt(timestamp), @@ -265,7 +254,7 @@ export class Validator implements Contracts.Validator.Validator { await evm.calculateRoundValidators({ commitKey, - roundValidators: BigNumber.make(roundValidators).toBigInt(), + roundValidators: BigInt(roundValidators), specId: milestone.evmSpec, timestamp: BigInt(timestamp), validatorAddress: generatorAddress, diff --git a/packages/webhooks/source/conditions.ts b/packages/webhooks/source/conditions.ts index 716a4ab94f..dae8d248f3 100644 --- a/packages/webhooks/source/conditions.ts +++ b/packages/webhooks/source/conditions.ts @@ -1,16 +1,30 @@ import type { Contracts } from "@mainsail/contracts"; -import { BigNumber } from "@mainsail/utils"; - const toBoolean = (value): boolean => value.toString().toLowerCase().trim() === "true"; const compareBigNumber = ( - value: Contracts.Webhooks.ConditionBigNumberish, - expected: Contracts.Webhooks.ConditionBigNumberish, - comparison: Extract, + value: Contracts.Webhooks.BigNumberType, + expected: Contracts.Webhooks.BigNumberType, + comparison: "isGreaterThan" | "isGreaterThanEqual" | "isLessThan" | "isLessThanEqual", ): boolean => { try { - return BigNumber.make(value)[comparison](expected); + const v = BigInt(value); + const e = BigInt(expected); + + switch (comparison) { + case "isGreaterThan": { + return v > e; + } + case "isGreaterThanEqual": { + return v >= e; + } + case "isLessThan": { + return v < e; + } + case "isLessThanEqual": { + return v <= e; + } + } } catch { return false; } @@ -23,38 +37,26 @@ const eq = (actual: Contracts.Webhooks.ConditionPrimitive, expected: Contracts.W const falsy = (actual: Contracts.Webhooks.ConditionPrimitive): boolean => actual === false || !toBoolean(actual); -const gt = ( - actual: Contracts.Webhooks.ConditionBigNumberish, - expected: Contracts.Webhooks.ConditionBigNumberish, -): boolean => compareBigNumber(actual, expected, "isGreaterThan"); +const gt = (actual: Contracts.Webhooks.BigNumberType, expected: Contracts.Webhooks.BigNumberType): boolean => + compareBigNumber(actual, expected, "isGreaterThan"); -const gte = ( - actual: Contracts.Webhooks.ConditionBigNumberish, - expected: Contracts.Webhooks.ConditionBigNumberish, -): boolean => compareBigNumber(actual, expected, "isGreaterThanEqual"); +const gte = (actual: Contracts.Webhooks.BigNumberType, expected: Contracts.Webhooks.BigNumberType): boolean => + compareBigNumber(actual, expected, "isGreaterThanEqual"); -const lt = ( - actual: Contracts.Webhooks.ConditionBigNumberish, - expected: Contracts.Webhooks.ConditionBigNumberish, -): boolean => compareBigNumber(actual, expected, "isLessThan"); +const lt = (actual: Contracts.Webhooks.BigNumberType, expected: Contracts.Webhooks.BigNumberType): boolean => + compareBigNumber(actual, expected, "isLessThan"); -const lte = ( - actual: Contracts.Webhooks.ConditionBigNumberish, - expected: Contracts.Webhooks.ConditionBigNumberish, -): boolean => compareBigNumber(actual, expected, "isLessThanEqual"); +const lte = (actual: Contracts.Webhooks.BigNumberType, expected: Contracts.Webhooks.BigNumberType): boolean => + compareBigNumber(actual, expected, "isLessThanEqual"); -const between = ( - actual: Contracts.Webhooks.ConditionBigNumberish, - expected: Contracts.Webhooks.ConditionRange, -): boolean => gt(actual, expected.min) && lt(actual, expected.max); +const between = (actual: Contracts.Webhooks.BigNumberType, expected: Contracts.Webhooks.ConditionRange): boolean => + gt(actual, expected.min) && lt(actual, expected.max); const ne = (actual: Contracts.Webhooks.ConditionPrimitive, expected: Contracts.Webhooks.ConditionPrimitive): boolean => !eq(actual, expected); -const notBetween = ( - actual: Contracts.Webhooks.ConditionBigNumberish, - expected: Contracts.Webhooks.ConditionRange, -): boolean => !between(actual, expected); +const notBetween = (actual: Contracts.Webhooks.BigNumberType, expected: Contracts.Webhooks.ConditionRange): boolean => + !between(actual, expected); const regexp = (actual: string, expected: string | RegExp): boolean => new RegExp(expected).test(actual); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 07f257fd52..37342acaf9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1875,9 +1875,6 @@ importers: '@mainsail/kernel': specifier: workspace:* version: link:../kernel - '@mainsail/utils': - specifier: workspace:* - version: link:../utils ajv: specifier: 8.18.0 version: 8.18.0 @@ -2258,9 +2255,6 @@ importers: '@mainsail/constants': specifier: workspace:* version: link:../constants - '@mainsail/utils': - specifier: workspace:* - version: link:../utils devDependencies: '@mainsail/contracts': specifier: workspace:* diff --git a/tests/functional/consensus/source/custom-proposal.ts b/tests/functional/consensus/source/custom-proposal.ts index 6f37ffb1d8..53d9b7197d 100644 --- a/tests/functional/consensus/source/custom-proposal.ts +++ b/tests/functional/consensus/source/custom-proposal.ts @@ -2,7 +2,7 @@ import type { Consensus } from "@mainsail/consensus/distribution/consensus.js"; import { Identifiers } from "@mainsail/constants"; import type { Contracts } from "@mainsail/contracts"; import { Proposal } from "@mainsail/crypto-proposal"; -import { assert, BigNumber } from "@mainsail/utils"; +import { assert } from "@mainsail/utils"; import { randomBytes } from "crypto"; import dayjs from "dayjs"; @@ -44,9 +44,9 @@ export const makeCustomProposal = async ( // - transactions // - amount + fee - const totals: { amount: BigNumber; fee: BigNumber; gasUsed: number } = { - amount: BigNumber.ZERO, - fee: BigNumber.ZERO, + const totals: { amount: bigint; fee: bigint; gasUsed: number } = { + amount: 0n, + fee: 0n, gasUsed: 0, }; @@ -81,8 +81,8 @@ export const makeCustomProposal = async ( assert.string(transaction.hash); transactionData.push(transaction); - totals.amount = totals.amount.plus(transaction.value); - totals.fee = totals.fee.plus(BigNumber.make(transaction.gasPrice).times(result.gasUsed)); + totals.amount += transaction.value; + totals.fee += BigInt(transaction.gasPrice) * result.gasUsed; totals.gasUsed += Number(result.gasUsed); payloadBuffers.push(Buffer.from(transaction.hash, "hex")); @@ -101,7 +101,7 @@ export const makeCustomProposal = async ( const blockFactory = app.get(Identifiers.Cryptography.Block.Factory); const block = await blockFactory.make( { - fee: totals.fee.toBigInt(), + fee: totals.fee, gasUsed: totals.gasUsed, logsBloom: "0".repeat(512), number: Number(commitKey.blockNumber), @@ -173,7 +173,7 @@ export const makeTransactionBuilderContext = ( ...context, fundedWalletProvider: async ( context: { app: Contracts.Kernel.Application; wallets: Contracts.Crypto.KeyPair[] }, - amount?: BigNumber, + amount?: bigint, ): Promise => { // create a random wallet with funds (without sending a transaction) const { app } = context; @@ -192,7 +192,7 @@ export const makeTransactionBuilderContext = ( // .get(Identifiers.Cryptography.Identity.Address.Factory) // .fromPublicKey(randomKeyPair.publicKey); - // amount = amount ?? BigNumber.make("10000000000"); + // amount = amount ?? 10000000000n; // for (const node of nodes) { // const { walletRepository } = app diff --git a/tests/functional/resync/source/integrity.ts b/tests/functional/resync/source/integrity.ts index f7c527447b..02416b53af 100644 --- a/tests/functional/resync/source/integrity.ts +++ b/tests/functional/resync/source/integrity.ts @@ -89,9 +89,20 @@ const computeNodeTableHashes = async (node: Contracts.Kernel.Application): Promi return tableHashes; } +// const logWalletsTable = async (node: Contracts.Kernel.Application, name: string): Promise => { +// const wallets = await runDatabaseQuery(node.get(Identifiers.Application.Name), async (dataSource: TypeOrm.DataSource) => { +// return dataSource.query(`SELECT * FROM public.wallets ORDER BY address;`); +// }); + +// writeFileSync(`wallets_${name}.json`, JSON.stringify(wallets, null, 2)); +// } + const verifyIntegrity = async (t: typeof assert, syncNode: Contracts.Kernel.Application, restoreNode: Contracts.Kernel.Application): Promise => { await patchDatabase(syncNode, restoreNode); + // await logWalletsTable(syncNode, "syncNode"); + // await logWalletsTable(restoreNode, "restoreNode"); + const tableHashesSyncNode = await computeNodeTableHashes(syncNode); const tableHashesRestoreNode = await computeNodeTableHashes(restoreNode); @@ -168,7 +179,7 @@ const patchDatabase = async (syncNode: Contracts.Kernel.Application, restoreNode await dataSource.query(` UPDATE plugins - SET configuration = + SET configuration = jsonb_set( jsonb_set( configuration, diff --git a/tests/functional/resync/source/resync-legacy.test.ts b/tests/functional/resync/source/resync-legacy.test.ts index c17432425d..b9acea3720 100644 --- a/tests/functional/resync/source/resync-legacy.test.ts +++ b/tests/functional/resync/source/resync-legacy.test.ts @@ -23,7 +23,7 @@ describe<{ await verifyLegacyNodeIntegrity(assert, syncNode, dataDirectory); }); - it("should be ok", async ({ syncNode }) => { + it.only("should be ok", async ({ syncNode }) => { await waitBlock(syncNode, 5); }); @@ -64,4 +64,4 @@ describe<{ }); assert.true(await forgeTransactions(context, [txFromReceivedLegacyFunds])); }); -}); \ No newline at end of file +}); diff --git a/tests/functional/resync/source/resync.test.ts b/tests/functional/resync/source/resync.test.ts index baafe1f762..963e90f9ce 100644 --- a/tests/functional/resync/source/resync.test.ts +++ b/tests/functional/resync/source/resync.test.ts @@ -136,4 +136,4 @@ describe<{ it.skip("should be ok with legacy wallets", async ({ syncNode }) => { // TODO }); -}); \ No newline at end of file +}); diff --git a/tests/functional/resync/source/setup.ts b/tests/functional/resync/source/setup.ts index a1dd2571d6..7602f45642 100644 --- a/tests/functional/resync/source/setup.ts +++ b/tests/functional/resync/source/setup.ts @@ -9,6 +9,7 @@ import { Worker } from "./worker.js"; type PluginOptions = Record; + const setupSyncNode = async (dataDirectory: string): Promise => { const app = new Application(); diff --git a/tests/functional/transaction-pool-api/source/snapshot.ts b/tests/functional/transaction-pool-api/source/snapshot.ts index c8d7ed6280..479f0aabdc 100644 --- a/tests/functional/transaction-pool-api/source/snapshot.ts +++ b/tests/functional/transaction-pool-api/source/snapshot.ts @@ -9,14 +9,13 @@ import { import { Events, Identifiers } from "@mainsail/constants"; import { Identifiers as EvmConsensusIdentifiers } from "@mainsail/evm-consensus"; import { assert } from "@mainsail/test-runner"; -import { BigNumber } from "@mainsail/utils"; import { parseAbi, parseEventLogs } from "viem"; import { getAccountByAddressOrPublicKey, getLegacyColdWallets } from "./utilities.js"; interface WalletState { - balance: BigNumber; - nonce: BigNumber; + balance: bigint; + nonce: bigint; } export const takeSnapshot = async (app: Contracts.Kernel.Application): Promise => { @@ -77,8 +76,8 @@ export class Snapshot { public async add(account: Contracts.Evm.AccountInfoExtended): Promise { this.states[account.address] = { - balance: BigNumber.make(account.balance), - nonce: BigNumber.make(account.nonce), + balance: account.balance, + nonce: account.nonce, }; } @@ -92,14 +91,14 @@ export class Snapshot { public async addManualDelta(addressOrPublicKey: string, delta: Partial): Promise { const account = await getAccountByAddressOrPublicKey({ app: this.app }, addressOrPublicKey); if (!this.manualDeltas[account.address]) { - this.manualDeltas[account.address] = { balance: BigNumber.ZERO, nonce: BigNumber.ZERO }; + this.manualDeltas[account.address] = { balance: 0n, nonce: 0n }; } const manualDelta = this.manualDeltas[account.address]; if (delta.balance) { - manualDelta.balance = manualDelta.balance.plus(delta.balance); + manualDelta.balance += delta.balance; } if (delta.nonce) { - manualDelta.nonce = manualDelta.nonce.plus(delta.nonce); + manualDelta.nonce += delta.nonce; } } @@ -114,41 +113,41 @@ export class Snapshot { ApiDatabaseIdentifiers.WalletRepositoryFactory, ); - let totalSupplyDatabase = BigNumber.ZERO; + let totalSupplyDatabase = 0n; const databaseWallets = await walletRepositoryFactory().createQueryBuilder().select().getMany(); const databaseWalletsLookup: Record = databaseWallets.reduce((accumulator, current) => { - totalSupplyDatabase = totalSupplyDatabase.plus(current.balance); + totalSupplyDatabase += BigInt(current.balance); accumulator[current.address] = current; return accumulator; }, {}); // Verify final balance of all wallets matches with delta and snapshot taken at block 0 const validateBalance = async (account: Contracts.Evm.AccountInfoExtended): Promise => { - const currentBalance = BigNumber.make(account.balance); - const currentNonce = BigNumber.make(account.nonce); + const currentBalance = account.balance; + const currentNonce = account.nonce; const previousState = this.states[account.address] ?? { - balance: BigNumber.ZERO, - nonce: BigNumber.ZERO, + balance: 0n, + nonce: 0n, }; const walletDelta = accountDeltas[account.address] ?? { - balance: BigNumber.ZERO, - nonce: BigNumber.ZERO, + balance: 0n, + nonce: 0n, }; const expected = { - balance: previousState.balance.plus(walletDelta.balance), - nonce: previousState.nonce.plus(walletDelta.nonce), + balance: previousState.balance + walletDelta.balance, + nonce: previousState.nonce + walletDelta.nonce, }; let ok = true; - if (!currentBalance.isEqualTo(expected.balance)) { + if (currentBalance !== expected.balance) { // If it doesn't match; the discrepancy must come from a merged legacy cold wallet const legacyColdWallet = this.legacyColdWallets[account.address]; if ( !legacyColdWallet || - !BigNumber.make(legacyColdWallet.balance).isEqualTo(currentBalance.minus(expected.balance)) - ) { + legacyColdWallet.balance !== (currentBalance - expected.balance)) + { console.log( "-- BALANCE MISMATCH", account.address, @@ -157,14 +156,14 @@ export class Snapshot { "ACTUAL", currentBalance.toString(), "DIFF", - expected.balance.minus(currentBalance).toString(), + (expected.balance - currentBalance).toString(), ); ok = false; } } - if (!currentNonce.isEqualTo(expected.nonce)) { + if (currentNonce !== expected.nonce) { console.log( "-- NONCE MISMATCH", account.address, @@ -173,7 +172,7 @@ export class Snapshot { "ACTUAL", currentNonce.toString(), "DIFF", - expected.nonce.minus(currentNonce).toString(), + (expected.nonce - currentNonce).toString(), ); ok = false; @@ -185,15 +184,14 @@ export class Snapshot { ok = false; } else { - if (!expected.balance.isEqualTo(databaseWallet.balance)) { + if (expected.balance !== BigInt(databaseWallet.balance)) { // If it doesn't match; the discrepancy must come from a merged legacy cold wallet const legacyColdWallet = this.legacyColdWallets[account.address]; if ( !legacyColdWallet || - !BigNumber.make(legacyColdWallet.balance).isEqualTo( - BigNumber.make(databaseWallet.balance).minus(expected.balance), - ) - ) { + legacyColdWallet.balance !== ( + BigInt(databaseWallet.balance) - expected.balance) + ) { console.log( "-- DB WALLET BALANCE MISMATCH", account.address, @@ -202,13 +200,13 @@ export class Snapshot { "ACTUAL", databaseWallet.balance, "DIFF", - expected.balance.minus(databaseWallet.balance).toString(), + (expected.balance - BigInt(databaseWallet.balance)).toString(), ); ok = false; } } - if (!expected.nonce.isEqualTo(databaseWallet.nonce)) { + if (expected.nonce !== BigInt(databaseWallet.nonce)) { // Nonce of the internal address is incremented on each block which is suspect // to race condition here. Hence it needs special treatment: let nonceMismatch = true; @@ -250,7 +248,7 @@ export class Snapshot { // number of blocks + current round + number of deployed contracts const expectedNonce = numberOfBlocks + round + numberOfContracts; // console.log("-- COMPARING DEPLOYER WALLET", expectedNonce, deployerDbWallet, dbWallet); - if (BigNumber.make(expectedNonce).isEqualTo(deployerDatabaseWallet.nonce)) { + if (BigInt(expectedNonce) === BigInt(deployerDatabaseWallet.nonce)) { nonceMismatch = false; } }); @@ -265,7 +263,7 @@ export class Snapshot { "ACTUAL", databaseWallet.nonce, "DIFF", - expected.nonce.minus(databaseWallet.nonce).toString(), + (expected.nonce - BigInt(databaseWallet.nonce)).toString(), ); ok = false; } @@ -276,7 +274,7 @@ export class Snapshot { }; let allValid = true; - let totalSupply = BigNumber.ZERO; + let totalSupply = 0n; const evm = this.app.getTagged(Identifiers.Evm.Instance, "instance", "evm"); const { accounts } = await evm.getAccounts(0n, 1000n); for (let account of accounts) { @@ -290,7 +288,7 @@ export class Snapshot { }; } - totalSupply = totalSupply.plus(account.balance); + totalSupply += account.balance; if (!(await validateBalance(account))) { allValid = false; @@ -303,7 +301,7 @@ export class Snapshot { ); const databaseState = await stateRepositoryFactory().createQueryBuilder().select().getOneOrFail(); - if (!totalSupply.isEqualTo(databaseState.supply) && !totalSupply.isEqualTo(totalSupplyDatabase)) { + if (totalSupply !== BigInt(databaseState.supply) && totalSupply !== totalSupplyDatabase) { console.log("-- DB TOTAL SUPPLY MISMATCH", totalSupply, databaseState.supply, totalSupplyDatabase); allValid = false; } @@ -331,10 +329,10 @@ export class Snapshot { const account = await getAccountByAddressOrPublicKey({ app: this.app }, addressOrPublicKey); if (!accountDeltas[account.address]) { - accountDeltas[account.address] = { balance: BigNumber.ZERO, nonce: BigNumber.ZERO }; + accountDeltas[account.address] = { balance: 0n, nonce: 0n }; } - accountDeltas[account.address].balance = accountDeltas[account.address].balance.plus(delta); + accountDeltas[account.address].balance = accountDeltas[account.address].balance + delta; }; const positiveBalanceChange = async (addressOrPublicKey: string, amount: bigint): Promise => { @@ -350,12 +348,12 @@ export class Snapshot { if (!accountDeltas[account.address]) { accountDeltas[account.address] = { - balance: BigNumber.ZERO, - nonce: BigNumber.ZERO, + balance: 0n, + nonce: 0n, }; } - accountDeltas[account.address].nonce = accountDeltas[account.address].nonce.plus(BigNumber.ONE); + accountDeltas[account.address].nonce = accountDeltas[account.address].nonce + 1n; }; for (const block of blocks) { @@ -366,7 +364,7 @@ export class Snapshot { if (receipt) { const consumedGas = this.app .get(Identifiers.BlockchainUtils.FeeCalculator) - .calculateConsumed(transaction.gasPrice, Number(receipt.receipt.gasUsed)).toBigInt(); + .calculateConsumed(transaction.gasPrice, receipt.receipt.gasUsed); console.log( "found receipt with", receipt.sender, @@ -465,14 +463,14 @@ export class Snapshot { for (const [address, delta] of Object.entries(this.manualDeltas)) { if (!accountDeltas[address]) { accountDeltas[address] = { - balance: BigNumber.ZERO, - nonce: BigNumber.ZERO, + balance: 0n, + nonce: 0n, }; } const stateDelta = accountDeltas[address]; - stateDelta.balance = stateDelta.balance.plus(delta.balance); - stateDelta.nonce = stateDelta.nonce.plus(delta.nonce); + stateDelta.balance += delta.balance; + stateDelta.nonce += delta.nonce; } return { accountDeltas, lastHeight: blocks.at(-1)?.number ?? 0 }; diff --git a/tests/functional/transaction-pool-api/source/utilities.ts b/tests/functional/transaction-pool-api/source/utilities.ts index 24451f3584..385ba86875 100644 --- a/tests/functional/transaction-pool-api/source/utilities.ts +++ b/tests/functional/transaction-pool-api/source/utilities.ts @@ -1,7 +1,7 @@ import { Identifiers } from "@mainsail/constants"; import type { Contracts } from "@mainsail/contracts"; import { EvmCalls } from "@mainsail/test-transaction-builders"; -import { assert, BigNumber, sleep } from "@mainsail/utils"; +import { assert, sleep } from "@mainsail/utils"; import { randomBytes } from "crypto"; export const getAddressByPublicKey = async (app: Contracts.Kernel.Application, publicKey: string): Promise => { @@ -13,7 +13,7 @@ export const getAddressByPublicKey = async (app: Contracts.Kernel.Application, p export const getRandomFundedWallet = async ( context: { app: Contracts.Kernel.Application; wallets: Contracts.Crypto.KeyPair[] }, funder: Contracts.Crypto.KeyPair, - amount?: BigNumber, + amount?: bigint, ): Promise => { const { app @@ -29,9 +29,9 @@ export const getRandomFundedWallet = async ( .get(Identifiers.Cryptography.Identity.Address.Factory) .fromPublicKey(randomKeyPair.publicKey); - amount = amount ?? BigNumber.make("1000000000000000000"); + amount = amount ?? 1000000000000000000n; - const fundTx = await EvmCalls.makeEvmCall(context, { recipient, sender: funder, value: amount.toBigInt() }); + const fundTx = await EvmCalls.makeEvmCall(context, { recipient, sender: funder, value: amount }); await addTransactionsToPool(context, [fundTx]); await waitBlock(context); @@ -114,23 +114,23 @@ export const waitBlock = async ({ app }: { app: Contracts.Kernel.Application }, export const hasBalance = async ( { app }: { app: Contracts.Kernel.Application }, address: string, - balance: number | string | BigNumber, -): Promise => (await getBalanceByAddress(app, address)).isEqualTo(balance); + balance: number | string | bigint, +): Promise => (await getBalanceByAddress(app, address)) === BigInt(balance); export const publicKeyToAddress = async (app: Contracts.Kernel.Application, publicKey: string): Promise => app .get(Identifiers.Cryptography.Identity.Address.Factory) .fromPublicKey(publicKey); -export const getBalanceByPublicKey = async (app: Contracts.Kernel.Application, publicKey: string): Promise => { +export const getBalanceByPublicKey = async (app: Contracts.Kernel.Application, publicKey: string): Promise => { const address = await publicKeyToAddress(app, publicKey); return getBalanceByAddress(app, address); }; -export const getBalanceByAddress = async (app: Contracts.Kernel.Application, address: string): Promise => { +export const getBalanceByAddress = async (app: Contracts.Kernel.Application, address: string): Promise => { const instance = app.getTagged(Identifiers.Evm.Instance, "instance", "evm"); const accountInfo = await instance.getAccountInfo(address); - return BigNumber.make(accountInfo.balance); + return accountInfo.balance; }; export const isTransactionCommitted = async (