diff --git a/gascalc/2-paymaster.gas.ts b/gascalc/2-paymaster.gas.ts index 7f10eaaf..1efd08fa 100644 --- a/gascalc/2-paymaster.gas.ts +++ b/gascalc/2-paymaster.gas.ts @@ -1,35 +1,45 @@ import { parseEther } from 'ethers/lib/utils' -import { TestPaymasterAcceptAll__factory } from '../typechain' +import { VerifyingPaymaster, VerifyingPaymaster__factory } from '../typechain' import { ethers } from 'hardhat' -import { GasChecker } from './GasChecker' -import { Create2Factory } from '../src/Create2Factory' -import { hexValue } from '@ethersproject/bytes' +import { GasCheckCollector, GasChecker } from './GasChecker' const ethersSigner = ethers.provider.getSigner() -context.skip('Minimal Paymaster', function () { +context('Verifying Paymaster', function () { this.timeout(60000) const g = new GasChecker() - let paymasterAddress: string + let paymaster: VerifyingPaymaster + before(async () => { - const paymasterInit = hexValue(new TestPaymasterAcceptAll__factory(ethersSigner).getDeployTransaction(g.entryPoint().address).data!) - paymasterAddress = await new Create2Factory(ethers.provider, ethersSigner).deploy(paymasterInit, 0) - const paymaster = TestPaymasterAcceptAll__factory.connect(paymasterAddress, ethersSigner) + // const paymasterInit = hexValue(new TestPaymasterAcceptAll__factory(ethersSigner).getDeployTransaction(g.entryPoint().address).data!) + const entryPointAddress = g.entryPoint().address + paymaster = await new VerifyingPaymaster__factory(ethersSigner).deploy(entryPointAddress, g.accountOwner.address) + GasCheckCollector.inst.setContractName(paymaster.address, 'VerifyingPaymaster') + await paymaster.addStake(1, { value: 1 }) await g.entryPoint().depositTo(paymaster.address, { value: parseEther('10') }) }) - it('simple paymaster', async function () { - await g.addTestRow({ title: 'simple paymaster', count: 1, paymaster: paymasterAddress, diffLastGas: false }) + + it('verifying paymaster', async function () { + await g.createAccounts1(2) await g.addTestRow({ - title: 'simple paymaster with diff', + title: 'verifying paymaster', + count: 1, + paymaster: paymaster.address, + verifyingPaymaster: true, + diffLastGas: false + }) + await g.addTestRow({ + title: 'verifying paymaster with diff', count: 2, - paymaster: paymasterAddress, + paymaster: paymaster.address, + verifyingPaymaster: true, diffLastGas: true }) }) - it('simple paymaster 10', async function () { + it.skip('simple paymaster 10', async function () { if (g.skipLong()) this.skip() await g.addTestRow({ title: 'simple paymaster', count: 10, paymaster: paymasterAddress, diffLastGas: false }) diff --git a/gascalc/GasChecker.ts b/gascalc/GasChecker.ts index 34a65cc5..6cd3ddc6 100644 --- a/gascalc/GasChecker.ts +++ b/gascalc/GasChecker.ts @@ -1,16 +1,21 @@ // calculate gas usage of different bundle sizes import '../test/aa.init' -import { defaultAbiCoder, hexConcat, parseEther } from 'ethers/lib/utils' +import { arrayify, defaultAbiCoder, hexConcat, parseEther } from 'ethers/lib/utils' import { AddressZero, checkForGeth, - createAddress, createAccountOwner, - deployEntryPoint, decodeRevertReason + createAddress, + decodeRevertReason, + deployEntryPoint } from '../test/testutils' import { - EntryPoint, EntryPoint__factory, SimpleAccountFactory, - SimpleAccountFactory__factory, SimpleAccount__factory + EntryPoint, + EntryPoint__factory, + SimpleAccount__factory, + SimpleAccountFactory, + SimpleAccountFactory__factory, + VerifyingPaymaster__factory } from '../typechain' import { BigNumberish, Wallet } from 'ethers' import hre from 'hardhat' @@ -20,7 +25,7 @@ import { table, TableUserConfig } from 'table' import { Create2Factory } from '../src/Create2Factory' import * as fs from 'fs' import { SimpleAccountInterface } from '../typechain/contracts/samples/SimpleAccount' -import { PackedUserOperation } from '../test/UserOperation' +import { PackedUserOperation, UserOperation } from '../test/UserOperation' import { expect } from 'chai' const gasCheckerLogFile = './reports/gas-checker.txt' @@ -42,6 +47,7 @@ interface GasTestInfo { title: string diffLastGas: boolean paymaster: string + verifyingPaymaster: boolean count: number // address, or 'random' or 'self' (for account itself) dest: string @@ -198,8 +204,6 @@ export class GasChecker { const userOps = await Promise.all(range(info.count) .map(index => Object.entries(this.accounts)[index]) .map(async ([account, accountOwner]) => { - const paymaster = info.paymaster - let { dest, destValue, destCallData } = info if (dest === 'self') { dest = account @@ -230,18 +234,28 @@ export class GasChecker { } // console.debug('== account est=', accountEst.toString()) accountEst = est.accountEst - const op = await fillSignAndPack({ + const userOpInput: Partial = { sender: account, callData: accountExecFromEntryPoint, maxPriorityFeePerGas: info.gasPrice, maxFeePerGas: info.gasPrice, callGasLimit: accountEst, verificationGasLimit: 1000000, - paymaster: paymaster, + paymaster: info.paymaster, paymasterVerificationGasLimit: 50000, paymasterPostOpGasLimit: 50000, preVerificationGas: 1 - }, accountOwner, GasCheckCollector.inst.entryPoint) + } + if (info.verifyingPaymaster) { + const MOCK_VALID_UNTIL = '0x00000000deadbeef' + const MOCK_VALID_AFTER = '0x0000000000001234' + const userOp1 = await fillUserOp(userOpInput, this.entryPoint()) + const paymaster = VerifyingPaymaster__factory.connect(info.paymaster, ethersSigner) + const hash = await paymaster.getHash(packUserOp(userOp1), MOCK_VALID_UNTIL, MOCK_VALID_AFTER) + const sig = await this.accountOwner.signMessage(arrayify(hash)) + userOpInput.paymasterData = hexConcat([defaultAbiCoder.encode(['uint48', 'uint48'], [MOCK_VALID_UNTIL, MOCK_VALID_AFTER]), sig]) + } + const op = await fillSignAndPack(userOpInput, accountOwner, GasCheckCollector.inst.entryPoint) // const packed = packUserOp(op, false) // console.log('== packed cost=', callDataCost(packed), packed) return op