From a44e20b4addd9555be2fc1bf9e656a2f8c8e9be4 Mon Sep 17 00:00:00 2001 From: Jonas Daniels Date: Mon, 26 Feb 2024 22:30:47 -0800 Subject: [PATCH] add more benchmarks --- .../benchmarks/encode-transaction.bench.ts | 154 ++++++++++++++++++ .../benchmarks/read-contract.bench.ts | 75 +++++++-- .../benchmarks/send-transaction.bench.ts | 66 ++++++++ 3 files changed, 285 insertions(+), 10 deletions(-) create mode 100644 packages/thirdweb/benchmarks/encode-transaction.bench.ts create mode 100644 packages/thirdweb/benchmarks/send-transaction.bench.ts diff --git a/packages/thirdweb/benchmarks/encode-transaction.bench.ts b/packages/thirdweb/benchmarks/encode-transaction.bench.ts new file mode 100644 index 00000000000..c6451468ec4 --- /dev/null +++ b/packages/thirdweb/benchmarks/encode-transaction.bench.ts @@ -0,0 +1,154 @@ +import { describe, bench } from "vitest"; + +// local imports +import { + createThirdwebClient, + getContract, + defineChain, + encode, + prepareContractCall, +} from ".."; +import { ThirdwebSDK } from "../../sdk"; +import { LocalWallet } from "../../wallets"; + +const SECRET_KEY = process.env.TW_SECRET_KEY as string; + +const LOCAL_RPC = "http://localhost:8555"; +const USDC_CONTRACT_ADDRESS = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"; +const VITALIK_WALLET = "0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B"; + +const client = createThirdwebClient({ + secretKey: SECRET_KEY, +}); + +const NEW_CONTRACT = getContract({ + chain: defineChain({ + id: 1, + rpc: LOCAL_RPC, + }), + client, + address: USDC_CONTRACT_ADDRESS, +}); + +const wallet = new LocalWallet(); + +await wallet.generate(); + +const sdk = await ThirdwebSDK.fromWallet(wallet, LOCAL_RPC, { + secretKey: SECRET_KEY, + readonlySettings: { + chainId: 1, + rpcUrl: LOCAL_RPC, + }, +}); + +const OLD_CONTRACT = await sdk.getContract(USDC_CONTRACT_ADDRESS); + +function randomBigint() { + return BigInt(Math.floor(Math.random() * 1000)); +} + +describe.runIf(SECRET_KEY)("encode transfer (warm cache)", () => { + bench("thirdweb", async () => { + const tx = prepareContractCall({ + contract: NEW_CONTRACT, + method: "function transfer(address,uint256)", + params: [VITALIK_WALLET, randomBigint()], + }); + await encode(tx); + }); + + bench("@thirdweb-dev/sdk", async () => { + OLD_CONTRACT.prepare("transfer", [VITALIK_WALLET, randomBigint()]).encode(); + }); +}); + +describe.runIf(SECRET_KEY)("encode transfer (cold cache)", () => { + bench("thirdweb", async () => { + // init the client + const newClient = createThirdwebClient({ + secretKey: SECRET_KEY, + }); + // define chain + const chain = defineChain({ + id: 1, + rpc: LOCAL_RPC, + }); + // get contract + const contract = getContract({ + chain, + client: newClient, + address: USDC_CONTRACT_ADDRESS, + }); + + const tx = prepareContractCall({ + contract: contract, + method: "function transfer(address,uint256)", + params: [VITALIK_WALLET, randomBigint()], + }); + await encode(tx); + }); + + bench("@thirdweb-dev/sdk", async () => { + //get the contract + const contract = await sdk.getContract(USDC_CONTRACT_ADDRESS); + // actually read from the contract + contract.prepare("transfer", [VITALIK_WALLET, randomBigint()]).encode(); + }); +}); + +const ABI = [ + { + inputs: [ + { + internalType: "address", + name: "account", + type: "address", + }, + ], + name: "balanceOf", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, +] as const; + +describe.runIf(SECRET_KEY)("read contract (pre-defined abi)", () => { + bench("thirdweb", async () => { + // init the client + const newClient = createThirdwebClient({ + secretKey: SECRET_KEY, + }); + // define chain + const chain = defineChain({ + id: 1, + rpc: LOCAL_RPC, + }); + // get contract + const contract = getContract({ + chain, + client: newClient, + address: USDC_CONTRACT_ADDRESS, + }); + + const tx = prepareContractCall({ + contract: contract, + method: "function transfer(address,uint256)", + params: [VITALIK_WALLET, randomBigint()], + }); + await encode(tx); + }); + + bench("@thirdweb-dev/sdk", async () => { + //get the contract + const contract = await sdk.getContractFromAbi(USDC_CONTRACT_ADDRESS, ABI); + // actually read from the contract + contract.prepare("transfer", [VITALIK_WALLET, randomBigint()]).encode(); + }); +}); diff --git a/packages/thirdweb/benchmarks/read-contract.bench.ts b/packages/thirdweb/benchmarks/read-contract.bench.ts index d004d9db1c3..bbdc3051ac9 100644 --- a/packages/thirdweb/benchmarks/read-contract.bench.ts +++ b/packages/thirdweb/benchmarks/read-contract.bench.ts @@ -9,9 +9,6 @@ import { } from ".."; import { ThirdwebSDK } from "../../sdk"; -// eslint-disable-next-line @typescript-eslint/no-var-requires -require("dotenv-mono").load(); - const SECRET_KEY = process.env.TW_SECRET_KEY as string; const LOCAL_RPC = "http://localhost:8555"; @@ -39,6 +36,14 @@ const OLD_CONTRACT = await new ThirdwebSDK(LOCAL_RPC, { }, }).getContract(USDC_CONTRACT_ADDRESS); +const sdk = new ThirdwebSDK(LOCAL_RPC, { + secretKey: SECRET_KEY, + readonlySettings: { + chainId: 1, + rpcUrl: LOCAL_RPC, + }, +}); + describe.runIf(SECRET_KEY)("read contract (warm cache)", () => { bench("thirdweb", async () => { await readContract({ @@ -79,16 +84,66 @@ describe.runIf(SECRET_KEY)("read contract (cold cache)", () => { }); bench("@thirdweb-dev/sdk", async () => { - // init the sdk - const sdk = new ThirdwebSDK(LOCAL_RPC, { - secretKey: SECRET_KEY, - readonlySettings: { - chainId: 1, - rpcUrl: LOCAL_RPC, + //get the contract + const contract = await sdk.getContract(USDC_CONTRACT_ADDRESS); + // actually read from the contract + await contract.call("balanceOf", [VITALIK_WALLET]); + }); +}); + +const ABI = [ + { + inputs: [ + { + internalType: "address", + name: "account", + type: "address", + }, + ], + name: "balanceOf", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", }, + ], + stateMutability: "view", + type: "function", + }, +] as const; + +describe.runIf(SECRET_KEY)("read contract (pre-defined abi)", () => { + bench("thirdweb", async () => { + // init the client + const newClient = createThirdwebClient({ + secretKey: SECRET_KEY, + }); + // define chain + const chain = defineChain({ + id: 1, + rpc: LOCAL_RPC, + }); + // get contract + const contract = getContract({ + chain, + client: newClient, + address: USDC_CONTRACT_ADDRESS, + abi: ABI, }); + // actually read from the contract + await readContract({ + contract, + method: "balanceOf", + params: [VITALIK_WALLET], + }); + }); + + bench("@thirdweb-dev/sdk", async () => { + // init the sdk + //get the contract - const contract = await sdk.getContract(USDC_CONTRACT_ADDRESS); + const contract = await sdk.getContractFromAbi(USDC_CONTRACT_ADDRESS, ABI); // actually read from the contract await contract.call("balanceOf", [VITALIK_WALLET]); }); diff --git a/packages/thirdweb/benchmarks/send-transaction.bench.ts b/packages/thirdweb/benchmarks/send-transaction.bench.ts new file mode 100644 index 00000000000..a9491c7d7eb --- /dev/null +++ b/packages/thirdweb/benchmarks/send-transaction.bench.ts @@ -0,0 +1,66 @@ +import { describe, bench } from "vitest"; + +// local imports +import { + createThirdwebClient, + defineChain, + sendTransaction, + prepareTransaction, +} from ".."; +import { privateKeyAccount } from "../dist/esm/wallets/private-key"; +import { ThirdwebSDK } from "../../sdk/dist/thirdweb-dev-sdk.cjs"; + +const SECRET_KEY = process.env.TW_SECRET_KEY as string; + +const LOCAL_RPC = "http://localhost:8555"; +const VITALIK_WALLET = "0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B"; + +const client = createThirdwebClient({ + secretKey: SECRET_KEY, +}); + +const TEST_CHAIN = defineChain({ + id: 1, + rpc: LOCAL_RPC, +}); + +const PKEY = + "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"; + +const account = privateKeyAccount({ + privateKey: PKEY, + client, +}); + +const sdk = ThirdwebSDK.fromPrivateKey(PKEY, LOCAL_RPC, { + secretKey: SECRET_KEY, + readonlySettings: { + chainId: 1, + rpcUrl: LOCAL_RPC, + }, +}); + +// const OLD_CONTRACT = await sdk.getContract(USDC_CONTRACT_ADDRESS); + +function randomBigint() { + return BigInt(Math.floor(Math.random() * 1000)); +} + +describe.runIf(SECRET_KEY)("encode native transfer", () => { + bench("thirdweb", async () => { + const transaction = prepareTransaction({ + client, + chain: TEST_CHAIN, + value: randomBigint(), + to: VITALIK_WALLET, + }); + await sendTransaction({ transaction, account }); + }); + + bench("@thirdweb-dev/sdk", async () => { + await sdk.wallet.sendRawTransaction({ + to: VITALIK_WALLET, + value: randomBigint(), + }); + }); +});