Skip to content

Commit

Permalink
Merge pull request #440 from pimlicolabs/4337-rule-complaint
Browse files Browse the repository at this point in the history
Make bundler 100% compliant
  • Loading branch information
plusminushalf authored Feb 14, 2025
2 parents 1284f14 + 75acc79 commit 335cd8b
Show file tree
Hide file tree
Showing 17 changed files with 350 additions and 107 deletions.
2 changes: 1 addition & 1 deletion src/cli/handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ export async function bundlerHandler(args_: IOptionsInput): Promise<void> {

const chain: Chain = {
id: chainId,
name: 'chain-name', // isn't important, never used
name: "chain-name", // isn't important, never used
nativeCurrency: {
name: "ETH",
symbol: "ETH",
Expand Down
6 changes: 3 additions & 3 deletions src/executor/executorManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,12 +167,12 @@ export class ExecutorManager {
}

// Debug endpoint
async sendBundleNow(): Promise<Hash> {
async sendBundleNow(): Promise<Hash | undefined> {
const bundles = await this.mempool.getBundles(1)
const bundle = bundles[0]

if (bundle.userOps.length === 0) {
throw new Error("no ops to bundle")
if (bundles.length === 0 || bundle.userOps.length === 0) {
return
}

const txHash = await this.sendBundleToExecutor(bundle)
Expand Down
2 changes: 1 addition & 1 deletion src/executor/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ export const getAuthorizationList = (
): SignedAuthorizationList | undefined => {
const authList = userOpInfos
.map(({ userOp }) => userOp)
.map(({ eip7702Auth }) => eip7702Auth)
.map(({ eip7702auth }) => eip7702auth)
.filter(Boolean) as SignedAuthorizationList

return authList.length ? authList : undefined
Expand Down
67 changes: 47 additions & 20 deletions src/mempool/mempool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import {
type UserOperation,
ValidationErrors,
type ValidationResult,
UserOperationBundle,
UserOpInfo
type UserOperationBundle,
type UserOpInfo
} from "@alto/types"
import type { Metrics } from "@alto/utils"
import type { Logger } from "@alto/utils"
Expand Down Expand Up @@ -274,7 +274,6 @@ export class MemoryMempool {
]
}

this.reputationManager.updateUserOperationSeenStatus(userOp, entryPoint)
const oldUserOpInfo = [
...outstandingOps,
...processedOrSubmittedOps
Expand Down Expand Up @@ -347,15 +346,24 @@ export class MemoryMempool {
newOp.maxFeePerGas >=
scaleBigIntByPercent(oldOp.maxFeePerGas, 110n)

const hasHigherFees = hasHigherPriorityFee || hasHigherMaxFee
const hasHigherFees = hasHigherPriorityFee && hasHigherMaxFee

if (!hasHigherFees) {
return [false, reason]
}

this.store.removeOutstanding(oldUserOpInfo.userOpHash)
this.reputationManager.replaceUserOperationSeenStatus(
oldOp,
entryPoint
)
}

this.reputationManager.increaseUserOperationSeenStatus(
userOp,
entryPoint
)

// Check if mempool already includes max amount of parallel user operations
const parallelUserOperationsCount = this.store
.dumpOutstanding()
Expand Down Expand Up @@ -571,6 +579,11 @@ export class MemoryMempool {
"2nd Validation error"
)
this.store.removeOutstanding(userOpHash)
this.reputationManager.decreaseUserOperationSeenStatus(
userOp,
entryPoint,
e instanceof RpcError ? e.message : JSON.stringify(e)
)
return {
skip: true,
paymasterDeposit,
Expand Down Expand Up @@ -834,10 +847,10 @@ export class MemoryMempool {

const [nonceKey, nonceSequence] = getNonceKeyAndSequence(userOp.nonce)

let currentNonceValue: bigint = BigInt(0)
let currentNonceSequence: bigint = BigInt(0)

if (_currentNonceValue) {
currentNonceValue = _currentNonceValue
currentNonceSequence = _currentNonceValue
} else {
const getNonceResult = await entryPointContract.read.getNonce(
[userOp.sender, nonceKey],
Expand All @@ -846,7 +859,7 @@ export class MemoryMempool {
}
)

currentNonceValue = getNonceKeyAndSequence(getNonceResult)[1]
currentNonceSequence = getNonceKeyAndSequence(getNonceResult)[1]
}

const outstanding = this.store
Expand All @@ -857,25 +870,39 @@ export class MemoryMempool {
const [mempoolNonceKey, mempoolNonceSequence] =
getNonceKeyAndSequence(mempoolUserOp.nonce)

let isPaymasterSame = false

if (isVersion07(userOp) && isVersion07(mempoolUserOp)) {
isPaymasterSame =
mempoolUserOp.paymaster === userOp.paymaster &&
!(
mempoolUserOp.sender === userOp.sender &&
mempoolNonceKey === nonceKey &&
mempoolNonceSequence === nonceSequence
) &&
userOp.paymaster !== null
}

return (
mempoolUserOp.sender === userOp.sender &&
mempoolNonceKey === nonceKey &&
mempoolNonceSequence >= currentNonceValue &&
mempoolNonceSequence < nonceSequence
(mempoolUserOp.sender === userOp.sender &&
mempoolNonceKey === nonceKey &&
mempoolNonceSequence >= currentNonceSequence &&
mempoolNonceSequence < nonceSequence) ||
isPaymasterSame
)
})

outstanding.sort((a, b) => {
const aUserOp = a.userOp
const bUserOp = b.userOp
return outstanding
.sort((a, b) => {
const aUserOp = a.userOp
const bUserOp = b.userOp

const [, aNonceValue] = getNonceKeyAndSequence(aUserOp.nonce)
const [, bNonceValue] = getNonceKeyAndSequence(bUserOp.nonce)
const [, aNonceValue] = getNonceKeyAndSequence(aUserOp.nonce)
const [, bNonceValue] = getNonceKeyAndSequence(bUserOp.nonce)

return Number(aNonceValue - bNonceValue)
})

return outstanding.map((userOpInfo) => userOpInfo.userOp)
return Number(aNonceValue - bNonceValue)
})
.map((userOpInfo) => userOpInfo.userOp)
}

clear(): void {
Expand Down
Loading

0 comments on commit 335cd8b

Please sign in to comment.