Skip to content

Commit

Permalink
feat: configurable whitelist (#119)
Browse files Browse the repository at this point in the history
  • Loading branch information
0xSulpiride authored Nov 21, 2023
1 parent 79376dc commit 01600a4
Show file tree
Hide file tree
Showing 26 changed files with 128 additions and 272 deletions.
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,12 @@ Or follow the steps below:
"enforceGasPrice": false, # do not bundle userops with low gas prices
"enforceGasPriceThreshold": 1000, # gas price threshold in bps. If set to 500, userops' gas price is allowed to be 5% lower than the network's gas price
"eip2930": false, # enables eip-2930
"useropsTTL": 300 # Userops time to live (in seconds)
"useropsTTL": 300, # Userops time to live (in seconds)
"whitelistedEntities": { # Entities that bypass stake and opcode validation (array of addresses)
"factory": [],
"paymaster": [],
"account": []
}
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion lerna.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
],
"npmClient": "yarn",
"useWorkspaces": true,
"version": "1.0.21-alpha",
"version": "1.0.22-alpha",
"stream": "true",
"command": {
"version": {
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "root",
"private": true,
"version": "1.0.21-alpha",
"version": "1.0.22-alpha",
"engines": {
"node": ">=18.0.0"
},
Expand Down
8 changes: 4 additions & 4 deletions packages/api/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "api",
"version": "1.0.21-alpha",
"version": "1.0.22-alpha",
"description": "The API module of Etherspot bundler client",
"author": "Etherspot",
"homepage": "https://https://github.com/etherspot/skandha#readme",
Expand Down Expand Up @@ -35,13 +35,13 @@
"class-transformer": "0.5.1",
"class-validator": "0.14.0",
"ethers": "5.7.2",
"executor": "^1.0.21-alpha",
"executor": "^1.0.22-alpha",
"fastify": "4.14.1",
"monitoring": "^1.0.21-alpha",
"monitoring": "^1.0.22-alpha",
"pino": "8.11.0",
"pino-pretty": "10.0.0",
"reflect-metadata": "0.1.13",
"types": "^1.0.21-alpha"
"types": "^1.0.22-alpha"
},
"devDependencies": {
"@types/connect": "3.4.35"
Expand Down
2 changes: 1 addition & 1 deletion packages/api/src/modules/redirect.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { providers } from "ethers";
import { Config } from "executor/lib/config";
import { NetworkName } from "types/src";
import { NetworkName } from "types/lib";

export class RedirectAPI {
private provider: providers.JsonRpcProvider;
Expand Down
14 changes: 7 additions & 7 deletions packages/cli/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "cli",
"version": "1.0.21-alpha",
"version": "1.0.22-alpha",
"description": "> TODO: description",
"author": "zincoshine <[email protected]>",
"homepage": "https://https://github.com/etherspot/skandha#readme",
Expand Down Expand Up @@ -38,15 +38,15 @@
"@libp2p/peer-id-factory": "2.0.1",
"@libp2p/prometheus-metrics": "1.1.3",
"@multiformats/multiaddr": "12.1.3",
"api": "^1.0.21-alpha",
"db": "^1.0.21-alpha",
"executor": "^1.0.21-alpha",
"api": "^1.0.22-alpha",
"db": "^1.0.22-alpha",
"executor": "^1.0.22-alpha",
"find-up": "5.0.0",
"got": "12.5.3",
"js-yaml": "4.1.0",
"monitoring": "^1.0.21-alpha",
"node": "^1.0.21-alpha",
"types": "^1.0.21-alpha",
"monitoring": "^1.0.22-alpha",
"node": "^1.0.22-alpha",
"types": "^1.0.22-alpha",
"yargs": "17.6.2"
},
"devDependencies": {
Expand Down
4 changes: 2 additions & 2 deletions packages/db/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "db",
"version": "1.0.21-alpha",
"version": "1.0.22-alpha",
"description": "The DB module of Etherspot bundler client",
"author": "Etherspot",
"homepage": "https://github.com/etherspot/etherspot-bundler#readme",
Expand Down Expand Up @@ -33,7 +33,7 @@
"dependencies": {
"@chainsafe/ssz": "0.10.1",
"@farcaster/rocksdb": "5.5.0",
"types": "^1.0.21-alpha"
"types": "^1.0.22-alpha"
},
"devDependencies": {
"@types/rocksdb": "3.0.1",
Expand Down
8 changes: 4 additions & 4 deletions packages/executor/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "executor",
"version": "1.0.21-alpha",
"version": "1.0.22-alpha",
"description": "The Relayer module of Etherspot bundler client",
"author": "Etherspot",
"homepage": "https://https://github.com/etherspot/skandha#readme",
Expand Down Expand Up @@ -33,8 +33,8 @@
"dependencies": {
"async-mutex": "0.4.0",
"ethers": "5.7.2",
"monitoring": "^1.0.21-alpha",
"params": "^1.0.21-alpha",
"types": "^1.0.21-alpha"
"monitoring": "^1.0.22-alpha",
"params": "^1.0.22-alpha",
"types": "^1.0.22-alpha"
}
}
74 changes: 56 additions & 18 deletions packages/executor/src/config.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// TODO: create a new package "config" instead of this file and refactor
import { Wallet, providers, utils } from "ethers";
import { NetworkName } from "types/lib";
import { IEntity } from "types/lib/executor";
import { getAddress } from "ethers/lib/utils";
import {
BundlerConfig,
ConfigOptions,
Expand Down Expand Up @@ -150,11 +152,19 @@ export class Config {
if (!conf) {
conf = {} as NetworkConfig;
}
const entryPoints = ENTRYPOINTS_ENV(network);
conf.entryPoints = entryPoints || conf.entryPoints;
conf.relayer = fromEnvVar(network, "RELAYER", conf.relayer);
conf.beneficiary = fromEnvVar(network, "BENEFICIARY", conf.beneficiary);
conf.rpcEndpoint = fromEnvVar(network, "RPC", conf.rpcEndpoint);
conf.entryPoints = fromEnvVar(
network,
"ENTRYPOINTS",
conf.entryPoints,
true
) as string[];
conf.relayer = fromEnvVar(network, "RELAYER", conf.relayer) as string;
conf.beneficiary = fromEnvVar(
network,
"BENEFICIARY",
conf.beneficiary
) as string;
conf.rpcEndpoint = fromEnvVar(network, "RPC", conf.rpcEndpoint) as string;

if (this.testingMode && !conf.rpcEndpoint) {
conf.rpcEndpoint = "http://localhost:8545"; // local geth
Expand All @@ -164,7 +174,7 @@ export class Config {
network,
"ETHERSCAN_API_KEY",
conf.etherscanApiKey || bundlerDefaultConfigs.etherscanApiKey
);
) as string;
conf.receiptLookupRange = Number(
fromEnvVar(
network,
Expand All @@ -184,7 +194,7 @@ export class Config {
network,
"RPC_SUBMIT",
conf.rpcEndpointSubmit || bundlerDefaultConfigs.rpcEndpointSubmit
);
) as string;
conf.gasPriceMarkup = Number(
fromEnvVar(
network,
Expand Down Expand Up @@ -230,6 +240,32 @@ export class Config {
)
);

if (!conf.whitelistedEntities) {
conf.whitelistedEntities = bundlerDefaultConfigs.whitelistedEntities;
}

/**
* validate whitelist addresses
*/
for (const entity of ["paymaster", "account", "factory"]) {
conf.whitelistedEntities[entity as IEntity] = fromEnvVar(
network,
`WL_${entity.toUpperCase()}`,
conf.whitelistedEntities[entity as IEntity],
true
) as string[];
const entities = conf.whitelistedEntities[entity as IEntity];
if (typeof entities != "undefined" && typeof entities != "object") {
throw new Error("Invalid config");
}
if (typeof entities == "object") {
for (const address of entities) {
// will throw error if the address is invalid
getAddress(address);
}
}
}

return Object.assign({}, bundlerDefaultConfigs, conf);
}
}
Expand All @@ -251,6 +287,7 @@ const bundlerDefaultConfigs: BundlerConfig = {
enforceGasPriceThreshold: 1000,
eip2930: false,
useropsTTL: 300, // 5 minutes
whitelistedEntities: { paymaster: [], account: [], factory: [] },
};

const NETWORKS_ENV = (): string[] | undefined => {
Expand All @@ -260,13 +297,6 @@ const NETWORKS_ENV = (): string[] | undefined => {
}
return undefined;
};
const ENTRYPOINTS_ENV = (network: string): string[] | undefined => {
const entryPoints = fromEnvVar(network, "ENTRYPOINTS", "");
if (entryPoints) {
return entryPoints.toLowerCase().replace(/ /g, "").split(",");
}
return undefined;
};

/**
* str = baseGoerli => SKANDHA_BASE_GOERLI
Expand All @@ -290,8 +320,16 @@ function getEnvVar<T>(envVar: string, fallback: T): T | string {
function fromEnvVar<T>(
networkName: string,
suffix = "",
fallback: T
): T | string {
const envVar = strToEnv(networkName, suffix);
return getEnvVar(envVar, fallback);
fallback: T,
isArray = false
): T | string | string[] {
const envVarName = strToEnv(networkName, suffix);
const envVarOrFallback = getEnvVar(envVarName, fallback);
if (isArray && typeof envVarOrFallback === "string") {
return (envVarOrFallback as string)
.toLowerCase()
.replace(/ /g, "")
.split(",");
}
return envVarOrFallback;
}
4 changes: 4 additions & 0 deletions packages/executor/src/interfaces.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { BigNumber, BigNumberish, BytesLike } from "ethers";
import { NetworkName } from "types/lib";
import { IWhitelistedEntities } from "types/lib/executor";
import { Executor } from "./executor";
import { MempoolEntry } from "./entities/MempoolEntry";

Expand Down Expand Up @@ -119,6 +120,9 @@ export interface NetworkConfig {
// default is 300 (5 minutes)
// after ttl you can replace a userop without increasing gas fees
useropsTTL: number;
// Entities that bypass stake and opcode validation
// https://eips.ethereum.org/EIPS/eip-4337#alternative-mempools
whitelistedEntities: IWhitelistedEntities;
}

export type BundlerConfig = Omit<
Expand Down
2 changes: 2 additions & 0 deletions packages/executor/src/modules/skandha.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,8 @@ export class Skandha {
this.networkConfig.enforceGasPriceThreshold
).toNumber(),
eip2930: this.networkConfig.eip2930,
useropsTTL: this.networkConfig.useropsTTL,
whitelistedEntities: this.networkConfig.whitelistedEntities,
};
}

Expand Down
1 change: 1 addition & 0 deletions packages/executor/src/services/UserOpValidation/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export class UserOpValidationService {
this.provider,
this.reputationService,
this.chainId,
this.networkConfig,
this.network,
this.logger
);
Expand Down
24 changes: 14 additions & 10 deletions packages/executor/src/services/UserOpValidation/validators/safe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ import { BigNumber, ethers, providers } from "ethers";
import { BundlerCollectorReturn, ExitInfo } from "types/lib/executor";
import RpcError from "types/lib/api/errors/rpc-error";
import * as RpcErrorCodes from "types/lib/api/errors/rpc-error-codes";
import { WhitelistedEntities } from "params/lib/whitelisted-entities";
import { NetworkName, Logger } from "types/lib";
import { IWhitelistedEntities } from "types/lib/executor";
import {
IWhitelistedEntities,
IWhitelistedEntity,
} from "params/lib/types/IWhitelistedEntities";
import { StorageMap, UserOpValidationResult } from "../../../interfaces";
NetworkConfig,
StorageMap,
UserOpValidationResult,
} from "../../../interfaces";
import { GethTracer } from "../GethTracer";
import {
callsFromEntryPointMethodSigs,
Expand Down Expand Up @@ -58,6 +58,7 @@ export class SafeValidationService {
private provider: providers.Provider,
private reputationService: ReputationService,
private chainId: number,
private networkConfig: NetworkConfig,
private network: NetworkName,
private logger: Logger
) {
Expand Down Expand Up @@ -255,15 +256,18 @@ export class SafeValidationService {
);
}

const whitelist: IWhitelistedEntity | undefined =
WhitelistedEntities[entityTitle as keyof IWhitelistedEntities];
const whitelist =
this.networkConfig.whitelistedEntities[
entityTitle as keyof IWhitelistedEntities
];
if (
entityAddr &&
whitelist != null &&
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
whitelist[this.chainId] &&
whitelist[this.chainId]!.some(
(addr) => addr === ethers.utils.getAddress(entityAddr)
whitelist.some(
(addr) =>
ethers.utils.getAddress(addr) ===
ethers.utils.getAddress(entityAddr)
)
) {
this.logger.debug(
Expand Down
4 changes: 2 additions & 2 deletions packages/monitoring/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "monitoring",
"version": "1.0.21-alpha",
"version": "1.0.22-alpha",
"description": "The Monitoring module of Etherspot bundler client",
"author": "Etherspot",
"homepage": "https://github.com/etherspot/etherspot-bundler#readme",
Expand Down Expand Up @@ -32,6 +32,6 @@
},
"dependencies": {
"prom-client": "^14.2.0",
"types": "^1.0.21-alpha"
"types": "^1.0.22-alpha"
}
}
Loading

0 comments on commit 01600a4

Please sign in to comment.