Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AA-227: Define JSON schema for the alt-mempool configuration #238

Merged
merged 30 commits into from
Jan 21, 2025
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
851cbd6
AA-227: Define JSON schema for the alt-mempool configuration
forshtat Jan 7, 2025
9c56201
Merge branch 'master' of github.com:eth-infinitism/bundler into AA-22…
forshtat Jan 12, 2025
cfa7fc9
WIP: Rewrite the ERC-7562 parser in a modular configurable way
forshtat Jan 12, 2025
449e29a
WIP: Add checks for OP-011 and OP-080
forshtat Jan 12, 2025
c43b1b9
WIP: Check OP-031 rules violations
forshtat Jan 12, 2025
23a64c3
WIP: Express some STO rules in readable format
forshtat Jan 13, 2025
266018f
More rules
forshtat Jan 13, 2025
a7ce5bb
Remove the old 'TracerResultsParser'
forshtat Jan 13, 2025
a9c6fca
Define and validate parser results schema
forshtat Jan 14, 2025
217e5b1
Remove new parser's dependency on the old tracer
forshtat Jan 14, 2025
f5804bd
Remove conversion function and make new tracer recursive as well
forshtat Jan 14, 2025
c496ee2
Clean up parser code
forshtat Jan 14, 2025
1697e56
Passes banned opcodes spec test
forshtat Jan 14, 2025
ec7b480
Fix some error reporting logic
forshtat Jan 19, 2025
0185e2e
Fix incorrect stake check
forshtat Jan 19, 2025
3d8f316
Fix EREP-060 and some other bugs
forshtat Jan 20, 2025
df3ec83
Fix associated storage attribution, struct access
forshtat Jan 20, 2025
951758f
Fix
forshtat Jan 20, 2025
21bc4b0
Clean up
forshtat Jan 20, 2025
bb0fadb
Undo removing the old parser
forshtat Jan 20, 2025
2310bdc
Skip opcode rules check for the code within EntryPoint
forshtat Jan 20, 2025
f295fe5
Fix typo
forshtat Jan 20, 2025
5f2c358
Fix not returning 'storageMap' and 'contractAddress' results
forshtat Jan 20, 2025
646c686
WIP: Add support for RIP-7560 transaction type
forshtat Jan 21, 2025
6f61c92
Configure AA_SENDER_CREATOR for ERC7562Parser
forshtat Jan 21, 2025
da7f986
Fix some issues with RIP-7560
forshtat Jan 21, 2025
a85db52
Enable legacy tracer and parser for the EIP-7702 tests
forshtat Jan 21, 2025
dd554cd
Handle the 'depth' field and clean up code for merging
forshtat Jan 21, 2025
44e16fb
Fix lint and depcheck
forshtat Jan 21, 2025
dd53eee
Fix lint
forshtat Jan 21, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions packages/bundler/src/BundlerConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export interface BundlerConfig {
chainId: number
beneficiary: string
entryPoint: string
senderCreator: string
gasFactor: string
minBalance: string
mnemonic: string
Expand Down Expand Up @@ -48,6 +49,7 @@ export const BundlerConfigShape = {
chainId: ow.number,
beneficiary: ow.string,
entryPoint: ow.string,
senderCreator: ow.string,
gasFactor: ow.string,
minBalance: ow.string,
mnemonic: ow.string,
Expand Down Expand Up @@ -102,6 +104,7 @@ export const bundlerConfigDefault: Partial<BundlerConfig> = {
port: '3000',
privateApiPort: '3001',
entryPoint: '0x0000000071727De22E5E9d8BAf0edAc6f37da032',
senderCreator: '0xefc2c1444ebcc4db75e7613d20c6a62ff67a167c',
unsafe: false,
conditionalRpc: false,
minStake: MIN_STAKE_VALUE,
Expand Down
8 changes: 6 additions & 2 deletions packages/bundler/src/modules/ExecutionManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { DepositManager } from './DepositManager'
import { BigNumberish, Signer } from 'ethers'
import { BundlerConfig } from '../BundlerConfig'
import { PreVerificationGasCalculator } from '@account-abstraction/sdk'
import { ERC7562Parser } from '@account-abstraction/validation-manager/dist/src/ERC7562Parser'

const debug = Debug('aa.exec')

Expand Down Expand Up @@ -147,11 +148,14 @@ export class ExecutionManager {

async _setConfiguration (configOverrides: Partial<BundlerConfig>): Promise<PreVerificationGasCalculator> {
const { configuration, entryPoint, unsafe } = this.validationManager._getDebugConfiguration()
const pvgc = new PreVerificationGasCalculator(Object.assign({}, configuration, configOverrides))
const mergedConfiguration = Object.assign({}, configuration, configOverrides)
const pvgc = new PreVerificationGasCalculator(mergedConfiguration)
const erc7562Parser = new ERC7562Parser(entryPoint.address, mergedConfiguration.senderCreator ?? '', true)
this.validationManager = new ValidationManager(
entryPoint,
unsafe,
pvgc
pvgc,
erc7562Parser
)
return pvgc
}
Expand Down
11 changes: 8 additions & 3 deletions packages/bundler/src/modules/initServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ import { BundlerReputationParams, ReputationManager } from './ReputationManager'
import { MempoolManager } from './MempoolManager'
import { BundleManager } from './BundleManager'
import {
AA_ENTRY_POINT,
AA_STAKE_MANAGER,
IValidationManager,
ValidationManager,
ValidationManagerRIP7560,
IValidationManager, AA_STAKE_MANAGER
} from '@account-abstraction/validation-manager'
import { BundlerConfig } from '../BundlerConfig'
import { EventsManager } from './EventsManager'
Expand All @@ -21,6 +23,7 @@ import { IBundleManager } from './IBundleManager'
import { DepositManager } from './DepositManager'
import { IRip7560StakeManager__factory } from '@account-abstraction/utils/dist/src/types'
import { PreVerificationGasCalculator, ChainConfigs } from '@account-abstraction/sdk'
import { ERC7562Parser } from '@account-abstraction/validation-manager/dist/src/ERC7562Parser'

/**
* initialize server modules.
Expand All @@ -38,13 +41,15 @@ export function initServer (config: BundlerConfig, signer: Signer): [ExecutionMa
let validationManager: IValidationManager
let bundleManager: IBundleManager
if (!config.rip7560) {
const erc7562Parser = new ERC7562Parser(entryPoint.address, config.senderCreator, true)
const tracerProvider = config.tracerRpcUrl == null ? undefined : getNetworkProvider(config.tracerRpcUrl)
validationManager = new ValidationManager(entryPoint, config.unsafe, preVerificationGasCalculator, tracerProvider)
validationManager = new ValidationManager(entryPoint, config.unsafe, preVerificationGasCalculator, erc7562Parser, tracerProvider)
bundleManager = new BundleManager(entryPoint, entryPoint.provider as JsonRpcProvider, signer, eventsManager, mempoolManager, validationManager, reputationManager,
config.beneficiary, parseEther(config.minBalance), config.maxBundleGas, config.conditionalRpc)
} else {
const erc7562Parser = new ERC7562Parser(AA_ENTRY_POINT, config.senderCreator, true)
const stakeManager = IRip7560StakeManager__factory.connect(AA_STAKE_MANAGER, signer)
validationManager = new ValidationManagerRIP7560(stakeManager, entryPoint.provider as JsonRpcProvider, config.unsafe)
validationManager = new ValidationManagerRIP7560(stakeManager, entryPoint.provider as JsonRpcProvider, erc7562Parser, config.unsafe)
bundleManager = new BundleManagerRIP7560(entryPoint.provider as JsonRpcProvider, signer, eventsManager, mempoolManager, validationManager, reputationManager,
config.beneficiary, parseEther(config.minBalance), config.maxBundleGas, config.conditionalRpc, false)
}
Expand Down
9 changes: 7 additions & 2 deletions packages/bundler/test/BundlerManager.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { ExecutionManager } from '../src/modules/ExecutionManager'
import { EventsManager } from '../src/modules/EventsManager'
import { createSigner } from './testUtils'
import { DepositManager } from '../src/modules/DepositManager'
import { ERC7562Parser } from '@account-abstraction/validation-manager/dist/src/ERC7562Parser'

describe('#BundlerManager', () => {
let bm: BundleManager
Expand All @@ -40,6 +41,7 @@ describe('#BundlerManager', () => {
chainId: 1337,
beneficiary: await signer.getAddress(),
entryPoint: entryPoint.address,
senderCreator: '0xefc2c1444ebcc4db75e7613d20c6a62ff67a167c',
gasFactor: '0.2',
minBalance: '0',
mnemonic: '',
Expand All @@ -63,7 +65,8 @@ describe('#BundlerManager', () => {
const repMgr = new ReputationManager(provider, BundlerReputationParams, parseEther(config.minStake), config.minUnstakeDelay)
const mempoolMgr = new MempoolManager(repMgr)
const preVerificationGasCalculator = new PreVerificationGasCalculator(MainnetConfig)
const validMgr = new ValidationManager(entryPoint, config.unsafe, preVerificationGasCalculator)
const erc7562Parser = new ERC7562Parser(entryPoint.address, config.senderCreator, true)
const validMgr = new ValidationManager(entryPoint, config.unsafe, preVerificationGasCalculator, erc7562Parser)
const evMgr = new EventsManager(entryPoint, mempoolMgr, repMgr)
bm = new BundleManager(entryPoint, entryPoint.provider as JsonRpcProvider, entryPoint.signer, evMgr, mempoolMgr, validMgr, repMgr, config.beneficiary, parseEther(config.minBalance), config.maxBundleGas, config.conditionalRpc)
})
Expand Down Expand Up @@ -97,6 +100,7 @@ describe('#BundlerManager', () => {
chainId: 1337,
beneficiary: await bundlerSigner.getAddress(),
entryPoint: _entryPoint.address,
senderCreator: '0xefc2c1444ebcc4db75e7613d20c6a62ff67a167c',
gasFactor: '0.2',
minBalance: '0',
mnemonic: '',
Expand All @@ -119,7 +123,8 @@ describe('#BundlerManager', () => {
const repMgr = new ReputationManager(provider, BundlerReputationParams, parseEther(config.minStake), config.minUnstakeDelay)
const mempoolMgr = new MempoolManager(repMgr)
const preVerificationGasCalculator = new PreVerificationGasCalculator(MainnetConfig)
const validMgr = new ValidationManager(_entryPoint, config.unsafe, preVerificationGasCalculator)
const erc7562Parser = new ERC7562Parser(entryPoint.address, config.senderCreator, true)
const validMgr = new ValidationManager(_entryPoint, config.unsafe, preVerificationGasCalculator, erc7562Parser)
const evMgr = new EventsManager(_entryPoint, mempoolMgr, repMgr)
bundleMgr = new BundleManager(_entryPoint, _entryPoint.provider as JsonRpcProvider, _entryPoint.signer, evMgr, mempoolMgr, validMgr, repMgr, config.beneficiary, parseEther(config.minBalance), config.maxBundleGas, false)
const depositManager = new DepositManager(entryPoint, mempoolMgr, bundleMgr)
Expand Down
5 changes: 4 additions & 1 deletion packages/bundler/test/BundlerServer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { ExecutionManager } from '../src/modules/ExecutionManager'
import { MethodHandlerERC4337 } from '../src/MethodHandlerERC4337'
import { BundlerConfig } from '../src/BundlerConfig'
import { DepositManager } from '../src/modules/DepositManager'
import { ERC7562Parser } from '@account-abstraction/validation-manager/dist/src/ERC7562Parser'

describe('BundleServer', function () {
let entryPoint: IEntryPoint
Expand All @@ -36,6 +37,7 @@ describe('BundleServer', function () {
chainId: 1337,
beneficiary: await signer.getAddress(),
entryPoint: entryPoint.address,
senderCreator: '0xefc2c1444ebcc4db75e7613d20c6a62ff67a167c',
gasFactor: '0.2',
minBalance: '0',
mnemonic: '',
Expand All @@ -59,7 +61,8 @@ describe('BundleServer', function () {
const repMgr = new ReputationManager(provider, BundlerReputationParams, parseEther(config.minStake), config.minUnstakeDelay)
const mempoolMgr = new MempoolManager(repMgr)
const preVerificationGasCalculator = new PreVerificationGasCalculator(MainnetConfig)
const validMgr = new ValidationManager(entryPoint, config.unsafe, preVerificationGasCalculator)
const erc7562Parser = new ERC7562Parser(entryPoint.address, config.senderCreator, true)
const validMgr = new ValidationManager(entryPoint, config.unsafe, preVerificationGasCalculator, erc7562Parser)
const evMgr = new EventsManager(entryPoint, mempoolMgr, repMgr)
const bundleMgr = new BundleManager(entryPoint, entryPoint.provider as JsonRpcProvider, entryPoint.signer, evMgr, mempoolMgr, validMgr, repMgr, config.beneficiary, parseEther(config.minBalance), config.maxBundleGas, false)
const depositManager = new DepositManager(entryPoint, mempoolMgr, bundleMgr)
Expand Down
5 changes: 4 additions & 1 deletion packages/bundler/test/DebugMethodHandler.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import { MethodHandlerERC4337 } from '../src/MethodHandlerERC4337'
import { createSigner } from './testUtils'
import { EventsManager } from '../src/modules/EventsManager'
import { DepositManager } from '../src/modules/DepositManager'
import { ERC7562Parser } from '@account-abstraction/validation-manager/dist/src/ERC7562Parser'

const provider = ethers.provider

Expand All @@ -46,6 +47,7 @@ describe('#DebugMethodHandler', () => {
chainId: 1337,
beneficiary: await signer.getAddress(),
entryPoint: entryPoint.address,
senderCreator: '0xefc2c1444ebcc4db75e7613d20c6a62ff67a167c',
gasFactor: '0.2',
minBalance: '0',
mnemonic: '',
Expand All @@ -69,7 +71,8 @@ describe('#DebugMethodHandler', () => {
const repMgr = new ReputationManager(provider, BundlerReputationParams, parseEther(config.minStake), config.minUnstakeDelay)
const mempoolMgr = new MempoolManager(repMgr)
const preVerificationGasCalculator = new PreVerificationGasCalculator(MainnetConfig)
const validMgr = new ValidationManager(entryPoint, config.unsafe, preVerificationGasCalculator)
const erc7562Parser = new ERC7562Parser(entryPoint.address, config.senderCreator, true)
const validMgr = new ValidationManager(entryPoint, config.unsafe, preVerificationGasCalculator, erc7562Parser)
const eventsManager = new EventsManager(entryPoint, mempoolMgr, repMgr)
const bundleMgr = new BundleManager(entryPoint, entryPoint.provider as JsonRpcProvider, entryPoint.signer, eventsManager, mempoolMgr, validMgr, repMgr,
config.beneficiary, parseEther(config.minBalance), config.maxBundleGas, false)
Expand Down
5 changes: 4 additions & 1 deletion packages/bundler/test/UserOpMethodHandler.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import { ethers } from 'hardhat'
import { createSigner } from './testUtils'
import { EventsManager } from '../src/modules/EventsManager'
import { DepositManager } from '../src/modules/DepositManager'
import { ERC7562Parser } from '@account-abstraction/validation-manager/dist/src/ERC7562Parser'

describe('UserOpMethodHandler', function () {
const helloWorld = 'hello world'
Expand Down Expand Up @@ -64,6 +65,7 @@ describe('UserOpMethodHandler', function () {
chainId: 1337,
beneficiary: await signer.getAddress(),
entryPoint: entryPoint.address,
senderCreator: '0xefc2c1444ebcc4db75e7613d20c6a62ff67a167c',
gasFactor: '0.2',
minBalance: '0',
mnemonic: '',
Expand All @@ -87,7 +89,8 @@ describe('UserOpMethodHandler', function () {
const repMgr = new ReputationManager(provider, BundlerReputationParams, parseEther(config.minStake), config.minUnstakeDelay)
mempoolMgr = new MempoolManager(repMgr)
const preVerificationGasCalculator = new PreVerificationGasCalculator(MainnetConfig)
const validMgr = new ValidationManager(entryPoint, config.unsafe, preVerificationGasCalculator)
const erc7562Parser = new ERC7562Parser(entryPoint.address, config.senderCreator, true)
const validMgr = new ValidationManager(entryPoint, config.unsafe, preVerificationGasCalculator, erc7562Parser)
const evMgr = new EventsManager(entryPoint, mempoolMgr, repMgr)
const bundleMgr = new BundleManager(entryPoint, entryPoint.provider as JsonRpcProvider, entryPoint.signer, evMgr, mempoolMgr, validMgr, repMgr, config.beneficiary, parseEther(config.minBalance), config.maxBundleGas, false)
const depositManager = new DepositManager(entryPoint, mempoolMgr, bundleMgr)
Expand Down
6 changes: 5 additions & 1 deletion packages/bundler/test/ValidateManager.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import {
TestTimeRangeAccountFactory,
TestTimeRangeAccountFactory__factory
} from '../src/types'
import { ERC7562Parser } from '@account-abstraction/validation-manager/dist/src/ERC7562Parser'

const cEmptyUserOp: UserOperation = {
sender: AddressZero,
Expand Down Expand Up @@ -154,7 +155,10 @@ describe('#ValidationManager', () => {

const unsafe = !await supportsDebugTraceCall(provider, false)
const preVerificationGasCalculator = new PreVerificationGasCalculator(MainnetConfig)
vm = new ValidationManager(entryPoint, unsafe, preVerificationGasCalculator)

const senderCreator = '0xefc2c1444ebcc4db75e7613d20c6a62ff67a167c'
const erc7562Parser = new ERC7562Parser(entryPoint.address, senderCreator, true)
vm = new ValidationManager(entryPoint, unsafe, preVerificationGasCalculator, erc7562Parser)

if (!await supportsDebugTraceCall(ethers.provider, false)) {
console.log('WARNING: opcode banning tests can only run with geth')
Expand Down
2 changes: 0 additions & 2 deletions packages/utils/src/interfaces/OperationBase.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { BigNumberish, BytesLike } from 'ethers'

import { EIP7702Authorization } from './EIP7702Authorization'

/**
* The operation interface that is shared by ERC-4337 and RIP-7560 types.
*/
Expand Down
10 changes: 10 additions & 0 deletions packages/validation-manager/src/AccountAbstractionEntity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export enum AccountAbstractionEntity {
account = 'account',
paymaster = 'paymaster',
factory = 'factory',
aggregator = 'aggregator',
senderCreator = 'SenderCreator',
entryPoint = 'EntryPoint',
nativeEntryPoint = 'NativeEntryPoint',
none = 'none'
}
14 changes: 9 additions & 5 deletions packages/validation-manager/src/BundlerCollectorTracer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,17 @@ export interface ExitInfo {
data: string
}

export interface StorageAccessInfos { [address: string]: AccessInfo }
export interface OpcodeInfos { [address: string]: number }
export interface ContractSizes { [address: string]: ContractSizeInfo }
export interface ExtCodeAccessInfos { [address: string]: string }

export interface TopLevelCallInfo {
// topLevelMethodSig: string
topLevelTargetAddress: string
opcodes: { [opcode: string]: number }
access: { [address: string]: AccessInfo }
contractSize: { [addr: string]: ContractSizeInfo }
extCodeAccessInfo: { [addr: string]: string }
opcodes: OpcodeInfos
access: StorageAccessInfos
contractSize: ContractSizes
extCodeAccessInfo: ExtCodeAccessInfos
oog?: boolean
calls?: []
type?: string
Expand Down
31 changes: 31 additions & 0 deletions packages/validation-manager/src/ERC7562BannedOpcodes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
* [OP-011] the opcodes banned for all entities.
*/
export const bannedOpCodes = new Set(
[
'BASEFEE',
'BLOCKHASH',
'COINBASE',
'DIFFICULTY',
'GAS',
'GASLIMIT',
'GASPRICE',
'INVALID',
'NUMBER',
'ORIGIN',
'PREVRANDAO',
'RANDOM',
'SELFDESTRUCT',
'TIMESTAMP'
]
)

/**
* [OP-080] the opcodes allowed in staked entities.
*/
export const opcodesOnlyInStakedEntities = new Set(
[
'BALANCE',
'SELFBALANCE'
]
)
76 changes: 76 additions & 0 deletions packages/validation-manager/src/ERC7562Call.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import ow from 'ow'

export interface ContractSize {
contractSize: number
opcode: number
}

export interface AccessedSlots {
reads?: Record<string, string[]>
transientReads?: Record<string, unknown>
transientWrites?: Record<string, unknown>
writes?: Record<string, number>
}

export interface ERC7562Call {
accessedSlots: AccessedSlots
contractSize: Record<string, ContractSize>
error?: string
extCodeAccessInfo: string[]
from: string
gas: string
gasUsed: string
input: string
outOfGas: boolean
output?: string
to: string
type: string
usedOpcodes: Record<number, number>
value?: string
calls?: ERC7562Call[]
keccak?: string[]
}

const contractSizeSchema = ow.object.exactShape({
contractSize: ow.number,
opcode: ow.number
})

const accessedSlotsSchema = ow.object.exactShape({
reads: ow.object.valuesOfType(ow.array.ofType(ow.string)),
transientReads: ow.object,
transientWrites: ow.object,
writes: ow.object.valuesOfType(ow.number)
})

const erc7562CallSchema = ow.object.exactShape({
accessedSlots: accessedSlotsSchema,
contractSize: ow.object.valuesOfType(contractSizeSchema),
error: ow.optional.string,
extCodeAccessInfo: ow.array.ofType(ow.string),
from: ow.string,
gas: ow.string,
gasUsed: ow.string,
input: ow.string,
outOfGas: ow.boolean,
output: ow.optional.string,
to: ow.string,
type: ow.string,
usedOpcodes: ow.object.valuesOfType(ow.number),
value: ow.optional.string,
calls: ow.optional.array,
keccak: ow.optional.array.ofType(ow.string)
})

/**
* Recursively check the calls ow schema.
*/
export function validateERC7562Call (value: ERC7562Call): void {
ow(value, erc7562CallSchema)

if (value.calls != null) {
for (const call of value.calls) {
validateERC7562Call(call)
}
}
}
Loading
Loading