From 6f537691b646caf1585fed03970343ec599368cd Mon Sep 17 00:00:00 2001 From: Alex Forshtat Date: Tue, 10 Oct 2023 16:34:31 +0300 Subject: [PATCH] Address PR comments --- packages/bundler/src/RpcTypes.ts | 2 +- packages/bundler/src/UserOpMethodHandler.ts | 4 +-- packages/bundler/src/modules/BundleManager.ts | 3 +- .../bundler/src/modules/ExecutionManager.ts | 2 +- .../bundler/src/modules/MempoolManager.ts | 2 +- packages/bundler/src/modules/Types.ts | 34 ------------------- packages/bundler/src/modules/initServer.ts | 3 +- packages/bundler/test/BundlerManager.test.ts | 3 +- .../bundler/test/UserOpMethodHandler.test.ts | 2 +- packages/utils/src/Utils.ts | 1 + packages/validation-manager/README.md | 2 +- .../src/TracerResultParser.ts | 24 +++++++++---- .../src/ValidationManager.ts | 5 ++- 13 files changed, 30 insertions(+), 57 deletions(-) delete mode 100644 packages/bundler/src/modules/Types.ts diff --git a/packages/bundler/src/RpcTypes.ts b/packages/bundler/src/RpcTypes.ts index dfd2895c..828ac568 100644 --- a/packages/bundler/src/RpcTypes.ts +++ b/packages/bundler/src/RpcTypes.ts @@ -1,6 +1,6 @@ import { BigNumberish } from 'ethers' import { TransactionReceipt } from '@ethersproject/providers' -import { UserOperation } from './modules/Types' +import { UserOperation } from '@account-abstraction/utils' /** * RPC calls return types diff --git a/packages/bundler/src/UserOpMethodHandler.ts b/packages/bundler/src/UserOpMethodHandler.ts index c7800658..bfeea705 100644 --- a/packages/bundler/src/UserOpMethodHandler.ts +++ b/packages/bundler/src/UserOpMethodHandler.ts @@ -7,9 +7,9 @@ import { deepHexlify, erc4337RuntimeVersion, requireCond, RpcError, tostr, getAd import { UserOperationStruct, EntryPoint } from '@account-abstraction/contracts' import { UserOperationEventEvent } from '@account-abstraction/contracts/dist/types/EntryPoint' import { calcPreVerificationGas } from '@account-abstraction/sdk' +import { UserOperation } from '@account-abstraction/utils' import { ExecutionManager } from './modules/ExecutionManager' import { UserOperationByHashResponse, UserOperationReceipt } from './RpcTypes' -import { ExecutionErrors, UserOperation } from './modules/Types' const HEX_REGEX = /^0x[a-fA-F\d]*$/i @@ -131,7 +131,7 @@ export class UserOpMethodHandler { data: userOp.callData }).then(b => b.toNumber()).catch(err => { const message = err.message.match(/reason="(.*?)"/)?.at(1) ?? 'execution reverted' - throw new RpcError(message, ExecutionErrors.UserOperationReverted) + throw new RpcError(message, ValidationErrors.UserOperationReverted) }) validAfter = BigNumber.from(validAfter) validUntil = BigNumber.from(validUntil) diff --git a/packages/bundler/src/modules/BundleManager.ts b/packages/bundler/src/modules/BundleManager.ts index 471d461d..2edacfcf 100644 --- a/packages/bundler/src/modules/BundleManager.ts +++ b/packages/bundler/src/modules/BundleManager.ts @@ -7,8 +7,7 @@ import Debug from 'debug' import { ReputationManager, ReputationStatus } from './ReputationManager' import { Mutex } from 'async-mutex' import { GetUserOpHashes__factory } from '../types' -import { UserOperation } from './Types' -import { StorageMap, getAddr, mergeStorageMap, runContractScript } from '@account-abstraction/utils' +import { UserOperation, StorageMap, getAddr, mergeStorageMap, runContractScript } from '@account-abstraction/utils' import { EventsManager } from './EventsManager' import { ErrorDescription } from '@ethersproject/abi/lib/interface' diff --git a/packages/bundler/src/modules/ExecutionManager.ts b/packages/bundler/src/modules/ExecutionManager.ts index cc6e7f1e..673c7743 100644 --- a/packages/bundler/src/modules/ExecutionManager.ts +++ b/packages/bundler/src/modules/ExecutionManager.ts @@ -1,12 +1,12 @@ import Debug from 'debug' import { Mutex } from 'async-mutex' import { ValidationManager } from '@account-abstraction/validation-manager' +import { UserOperation } from '@account-abstraction/utils' import { clearInterval } from 'timers' import { BundleManager, SendBundleReturn } from './BundleManager' import { MempoolManager } from './MempoolManager' import { ReputationManager } from './ReputationManager' -import { UserOperation } from './Types' const debug = Debug('aa.exec') diff --git a/packages/bundler/src/modules/MempoolManager.ts b/packages/bundler/src/modules/MempoolManager.ts index a7448b51..14a03741 100644 --- a/packages/bundler/src/modules/MempoolManager.ts +++ b/packages/bundler/src/modules/MempoolManager.ts @@ -9,7 +9,7 @@ import { } from '@account-abstraction/utils' import { ReputationManager } from './ReputationManager' import Debug from 'debug' -import { UserOperation } from './Types' +import { UserOperation } from '@account-abstraction/utils' const debug = Debug('aa.mempool') diff --git a/packages/bundler/src/modules/Types.ts b/packages/bundler/src/modules/Types.ts deleted file mode 100644 index c822978d..00000000 --- a/packages/bundler/src/modules/Types.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { NotPromise } from '@account-abstraction/utils' -import { - IEntryPoint__factory, - IPaymaster__factory, - SenderCreator__factory, - UserOperationStruct -} from '@account-abstraction/contracts' -import { - TestOpcodesAccountFactory__factory, - TestOpcodesAccount__factory, - TestStorageAccount__factory -} from '../types' - -export enum ExecutionErrors { - UserOperationReverted = -32521 -} - -export type UserOperation = NotPromise - -export const abi = Object.values([ - ...TestOpcodesAccount__factory.abi, - ...TestOpcodesAccountFactory__factory.abi, - ...TestStorageAccount__factory.abi, - ...SenderCreator__factory.abi, - ...IEntryPoint__factory.abi, - ...IPaymaster__factory.abi -].reduce((set, entry) => { - const key = `${entry.name}(${entry.inputs.map(i => i.type).join(',')})` - // console.log('key=', key, keccak256(Buffer.from(key)).slice(0,10)) - return { - ...set, - [key]: entry - } -}, {})) as any diff --git a/packages/bundler/src/modules/initServer.ts b/packages/bundler/src/modules/initServer.ts index 33890dea..a46492db 100644 --- a/packages/bundler/src/modules/initServer.ts +++ b/packages/bundler/src/modules/initServer.ts @@ -9,7 +9,6 @@ import { Signer } from 'ethers' import { BundlerConfig } from '../BundlerConfig' import { EventsManager } from './EventsManager' import { getNetworkProvider } from '../Config' -import { abi } from './Types' /** * initialize server modules. @@ -21,7 +20,7 @@ export function initServer (config: BundlerConfig, signer: Signer): [ExecutionMa const entryPoint = EntryPoint__factory.connect(config.entryPoint, signer) const reputationManager = new ReputationManager(getNetworkProvider(config.network), BundlerReputationParams, parseEther(config.minStake), config.minUnstakeDelay) const mempoolManager = new MempoolManager(reputationManager) - const validationManager = new ValidationManager(entryPoint, config.unsafe, abi) + const validationManager = new ValidationManager(entryPoint, config.unsafe) const eventsManager = new EventsManager(entryPoint, mempoolManager, reputationManager) const bundleManager = new BundleManager(entryPoint, eventsManager, mempoolManager, validationManager, reputationManager, config.beneficiary, parseEther(config.minBalance), config.maxBundleGas, config.conditionalRpc) diff --git a/packages/bundler/test/BundlerManager.test.ts b/packages/bundler/test/BundlerManager.test.ts index 23fb9d89..82014773 100644 --- a/packages/bundler/test/BundlerManager.test.ts +++ b/packages/bundler/test/BundlerManager.test.ts @@ -4,13 +4,12 @@ import { assert, expect } from 'chai' import { BundlerReputationParams, ReputationManager } from '../src/modules/ReputationManager' import { AddressZero, getUserOpHash } from '@account-abstraction/utils' -import { supportsDebugTraceCall } from '@account-abstraction/validation-manager' +import { ValidationManager, supportsDebugTraceCall } from '@account-abstraction/validation-manager' import { DeterministicDeployer } from '@account-abstraction/sdk' import { MempoolManager } from '../src/modules/MempoolManager' import { BundleManager } from '../src/modules/BundleManager' import { ethers } from 'hardhat' import { BundlerConfig } from '../src/BundlerConfig' -import { ValidationManager } from '../../validation-manager/src/ValidationManager' import { TestFakeWalletToken__factory } from '../src/types' import { UserOperation } from '../src/modules/Types' import { UserOpMethodHandler } from '../src/UserOpMethodHandler' diff --git a/packages/bundler/test/UserOpMethodHandler.test.ts b/packages/bundler/test/UserOpMethodHandler.test.ts index eea80d1a..0e8aa101 100644 --- a/packages/bundler/test/UserOpMethodHandler.test.ts +++ b/packages/bundler/test/UserOpMethodHandler.test.ts @@ -18,13 +18,13 @@ import { TestRulesAccount, TestRulesAccount__factory } from '../src/types' +import { ValidationManager } from '@account-abstraction/validation-manager' import { resolveHexlify, waitFor } from '@account-abstraction/utils' import { UserOperationEventEvent } from '@account-abstraction/contracts/dist/types/EntryPoint' import { UserOperationReceipt } from '../src/RpcTypes' import { ExecutionManager } from '../src/modules/ExecutionManager' import { BundlerReputationParams, ReputationManager } from '../src/modules/ReputationManager' import { MempoolManager } from '../src/modules/MempoolManager' -import { ValidationManager } from '../../validation-manager/src/ValidationManager' import { BundleManager } from '../src/modules/BundleManager' import { supportsDebugTraceCall } from '@account-abstraction/validation-manager' import { UserOpMethodHandler } from '../src/UserOpMethodHandler' diff --git a/packages/utils/src/Utils.ts b/packages/utils/src/Utils.ts index 7486ba86..2f35c31f 100644 --- a/packages/utils/src/Utils.ts +++ b/packages/utils/src/Utils.ts @@ -39,6 +39,7 @@ export enum ValidationErrors { InsufficientStake = -32505, UnsupportedSignatureAggregator = -32506, InvalidSignature = -32507, + UserOperationReverted = -32521 } export interface ReferencedCodeHashes { diff --git a/packages/validation-manager/README.md b/packages/validation-manager/README.md index d6eaab5e..52719d78 100644 --- a/packages/validation-manager/README.md +++ b/packages/validation-manager/README.md @@ -13,5 +13,5 @@ import { UserOperation } from '@account-abstraction/utils' import { checkRulesViolations } from '@account-abstraction/validation-manager' const userOperation: UserOperation = createUserOp() -checkRulesViolations(provider, userOperation, entryPoint) +await checkRulesViolations(provider, userOperation, entryPoint) ``` diff --git a/packages/validation-manager/src/TracerResultParser.ts b/packages/validation-manager/src/TracerResultParser.ts index 20765167..e19d17ff 100644 --- a/packages/validation-manager/src/TracerResultParser.ts +++ b/packages/validation-manager/src/TracerResultParser.ts @@ -7,7 +7,7 @@ import { IEntryPoint, IAccount__factory, IPaymaster__factory, - SenderCreator__factory + SenderCreator__factory, IEntryPoint__factory } from '@account-abstraction/contracts' import { BundlerTracerResult } from './BundlerCollectorTracer' import { @@ -34,6 +34,19 @@ interface CallEntry { value?: BigNumberish } +const abi = Object.values([ + ...SenderCreator__factory.abi, + ...IEntryPoint__factory.abi, + ...IPaymaster__factory.abi +].reduce((set, entry) => { + const key = `${entry.name}(${entry.inputs.map(i => i.type).join(',')})` + // console.log('key=', key, keccak256(Buffer.from(key)).slice(0,10)) + return { + ...set, + [key]: entry + } +}, {})) as any + /** * parse all call operation in the trace. * notes: @@ -43,8 +56,7 @@ interface CallEntry { * @param abi */ function parseCallStack ( - tracerResults: BundlerTracerResult, - abi: any[] = [] + tracerResults: BundlerTracerResult ): CallEntry[] { const xfaces = new Interface(abi) @@ -164,15 +176,13 @@ const callsFromEntryPointMethodSigs: { [key: string]: string } = { * @param tracerResults the tracer return value * @param validationResult output from simulateValidation * @param entryPoint the entryPoint that hosted the "simulatedValidation" traced call. - * @param abi * @return list of contract addresses referenced by this UserOp */ export function tracerResultParser ( userOp: UserOperation, tracerResults: BundlerTracerResult, validationResult: ValidationResult, - entryPoint: IEntryPoint, - abi: any[] = [] + entryPoint: IEntryPoint ): [string[], StorageMap] { debug('=== simulation result:', inspect(tracerResults, true, 10, true)) // todo: block access to no-code addresses (might need update to tracer) @@ -185,7 +195,7 @@ export function tracerResultParser ( if (Object.values(tracerResults.callsFromEntryPoint).length < 1) { throw new Error('Unexpected traceCall result: no calls from entrypoint.') } - const callStack = parseCallStack(tracerResults, abi) + const callStack = parseCallStack(tracerResults) const callInfoEntryPoint = callStack.find(call => call.to === entryPointAddress && call.from !== entryPointAddress && diff --git a/packages/validation-manager/src/ValidationManager.ts b/packages/validation-manager/src/ValidationManager.ts index 155dcaf4..6b12350c 100644 --- a/packages/validation-manager/src/ValidationManager.ts +++ b/packages/validation-manager/src/ValidationManager.ts @@ -57,8 +57,7 @@ const HEX_REGEX = /^0x[a-fA-F\d]*$/i export class ValidationManager { constructor ( readonly entryPoint: IEntryPoint, - readonly unsafe: boolean, - readonly abi: any[] = [] + readonly unsafe: boolean ) {} // standard eth_call to simulateValidation @@ -196,7 +195,7 @@ export class ValidationManager { let tracerResult: BundlerTracerResult [res, tracerResult] = await this._geth_traceCall_SimulateValidation(userOp) let contractAddresses: string[] - [contractAddresses, storageMap] = tracerResultParser(userOp, tracerResult, res, this.entryPoint, this.abi) + [contractAddresses, storageMap] = tracerResultParser(userOp, tracerResult, res, this.entryPoint) // if no previous contract hashes, then calculate hashes of contracts if (previousCodeHashes == null) { codeHashes = await this.getCodeHashes(contractAddresses)