Skip to content

Commit

Permalink
Merge pull request #746 from bcnmy/refactor/ethereum-bundler
Browse files Browse the repository at this point in the history
Proper JSON logging, flashbot polling & a lot of refactoring
  • Loading branch information
TheDivic authored Nov 14, 2024
2 parents b4819f1 + 03c0887 commit 92ed307
Show file tree
Hide file tree
Showing 29 changed files with 1,392 additions and 1,270 deletions.
13 changes: 12 additions & 1 deletion config/default.json
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@
},
"retryTransactionInterval": {
"137": 30000,
"1": 150000,
"1": 375000,
"97": 30000,
"56": 30000,
"1101": 30000,
Expand Down Expand Up @@ -1137,6 +1137,17 @@
"aaDashboardBackend": {
"url": "https://paymaster-dashboard-backend-v2.staging.biconomy.io/api/v2/bundlers/auth"
},
"flashbots": {
"rpcUrl": "https://rpc.flashbots.net/fast",
"statusUrl": "https://protect.flashbots.net/tx",
"getStatusIntervalDelay": 5000,
"maxBlockWait": 26,
"supportedNetworks": [1]
},
"clearStaleMessages": {
"supportedNetworks": [1, 11155111],
"ttlSeconds": 3600
},
"isTWSetup": false,
"redisCluster": {
"port": 6379,
Expand Down
4 changes: 4 additions & 0 deletions config/test.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
"dataSources": {
"redisUrl": "test"
},
"clearStaleMessages": {
"supportedNetworks": [1],
"ttlSeconds": 1
},
"chains": {
"providers": {
"1": [
Expand Down
254 changes: 51 additions & 203 deletions src/common/cache/redis/RedisCacheService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import nodeconfig from "config";
import { config } from "../../../config";
import { logger } from "../../logger";
import { ICacheService } from "../interface";
import { parseError } from "../../utils";

const log = logger.child({
module: module.filename.split("/").slice(-4).join("/"),
Expand Down Expand Up @@ -79,10 +78,16 @@ export class RedisCacheService implements ICacheService {
if (redisLock && this.redLock) {
await this.redLock.release(redisLock);
} else {
log.error("Redlock not initialized");
log.error(
{ redisLock: redisLock.toString() },
"Redlock not initialized",
);
}
} catch (error) {
log.error(`Error in unlocking redis lock ${parseError(error)}`);
} catch (err) {
log.error(
{ err, redisLock: redisLock.toString() },
`Error during redLock.release`,
);
}
}

Expand All @@ -101,29 +106,25 @@ export class RedisCacheService implements ICacheService {
* Method creates connection to redis client instance
*/
async connect(): Promise<void> {
log.info(
`Initiating Redis connection with current status as: ${this.redisClient.status}`,
);
const _log = log.child({
redisUrl: config.dataSources.redisUrl,
status: this.redisClient.status,
});
try {
_log.info(`Connecting to Redis`);
await this.redisClient.connect();
log.info(
`Main Redis connected successfully with status as: ${this.redisClient.status}`,
);
} catch (error) {
log.info(`Error in connecting to redis client ${error}`);
throw error;
_log.info(`Connected to Redis`);
} catch (err) {
log.info({ err }, `Error in RedisCacheService.connect()`);
throw err;
}
this.redLock = this.connectRedLock();

this.redLock.on("clientError", (err: object) => {
try {
log.info(`Failed to get redis lock ${err.toString()}`);
} catch (error) {
log.error(error);
}
_log.info({ err }, `redlock.clientError`);
});
this.redisClient.on("error", (err: unknown) => {
log.error(`Redis redisClient Error ${err}`);
log.error({ err }, `redisClient.clientError`);
});
}

Expand All @@ -141,21 +142,20 @@ export class RedisCacheService implements ICacheService {
* @returns true or false basis on success or failure
*/
async decrement(key: string, decrementBy: number = 1): Promise<boolean> {
log.info(`Checking if the key: ${key} exists`);
const _log = log.child({ key, decrementBy });

// could use get service also here
const val = await this.redisClient.get(key);
if (val == null || val === "undefined") {
log.info("Key does not exist. Nothing to decrement");
_log.info("Key does not exist. Nothing to decrement");
return false;
}
try {
log.info(
`Key exists. Decrementing cache value by ${decrementBy} => Key: ${key}`,
);
_log.info(`Key exists. Decrementing cache value`);
await this.redisClient.decrby(key, decrementBy);
return true;
} catch (error) {
log.error(`Error in decrement value ${parseError(error)}`);
} catch (err) {
_log.error({ err }, `Error in RedisCacheService.decrement()`);
}
return false;
}
Expand All @@ -166,13 +166,14 @@ export class RedisCacheService implements ICacheService {
* @returns true or false basis on success or failure
*/
async delete(key: string): Promise<boolean> {
log.info(`Deleting cache value => Key: ${key}`);
const _log = log.child({ key });
try {
_log.info(`RedisCacheService.delete()`);
const result = await this.redisClient.del(key);
if (result) return true;
return false;
} catch (error) {
log.error(`Error in deleting key ${key} - ${parseError(error)}`);
} catch (err) {
log.error({ err }, `Error in RedisCacheService.delete()`);
return false;
}
}
Expand All @@ -184,13 +185,14 @@ export class RedisCacheService implements ICacheService {
* @returns true or false basis on success or failure
*/
async expire(key: string, expiryTime: number): Promise<boolean> {
const _log = log.child({ key, expiryTime });
try {
log.info(`Setting expirtyTime: ${expiryTime} for key: ${key}`);
_log.info(`RedisCacheService.expire`);
const result = await this.redisClient.expire(key, expiryTime);
if (result) return true;
return false;
} catch (error) {
log.error(parseError(error));
} catch (err) {
log.error({ err }, "Error in RedisCacheService.expire");
return false;
}
}
Expand All @@ -201,12 +203,13 @@ export class RedisCacheService implements ICacheService {
* @returns string value that is set in cache
*/
async get(key: string): Promise<string> {
const _log = log.child({ key });
try {
log.info(`Getting key: ${key} from cache`);
_log.info(`RedisCacheService.get()`);
const result = (await this.redisClient.get(key)) || "";
return result;
} catch (error) {
log.error(`Error getting value for key ${key} - ${parseError(error)}`);
} catch (err) {
_log.error({ err }, `Error in RedisCacheService.get`);
}
return "";
}
Expand All @@ -218,23 +221,23 @@ export class RedisCacheService implements ICacheService {
* @returns true or false basis on success or failure
*/
async increment(key: string, incrementBy: number = 1): Promise<boolean> {
log.info(`Checking if the key: ${key} exists`);
const _log = log.child({ key, incrementBy });
try {
const val = await this.redisClient.get(key);
if (!val) {
log.info("Key does not exist. Nothing to increment");
_log.info("Key does not exist. Nothing to increment");
return false;
}

log.info(`Inrementing cache value by ${incrementBy} => Key: ${key}`);
_log.info(`Inrementing cache value`);
const result = await this.redisClient.incrby(key, incrementBy);
if (result) {
log.info(`Incremented cache value by ${incrementBy} => Key: ${key}`);
_log.info(`Incremented cache value`);
return true;
}
return false;
} catch (error) {
log.error(`Error in increment value - ${parseError(error)}`);
} catch (err) {
_log.error({ err }, `Error in RedisCacheService.increment`);
return false;
}
}
Expand All @@ -251,172 +254,17 @@ export class RedisCacheService implements ICacheService {
value: string,
hideValueInLogs: boolean = false,
): Promise<boolean> {
if (!hideValueInLogs) {
log.info(`Setting cache value => Key: ${key} Value: ${value}`);
} else {
log.info(`Setting value in cache with key: ${key}`);
}
const _log = hideValueInLogs
? log.child({ key })
: log.child({ key, value });

_log.info(`RedisCacheService.set`);
try {
await this.redisClient.set(key, value);
log.info(`Cache value set in logs for key: ${key}`);
return true;
} catch (error) {
log.error(
`Error setting value ${value} for key ${key} - ${parseError(error)}`,
);
} catch (err) {
_log.error({ err }, `Error in RedisCacheService.set()`);
return false;
}
}
}

// export class RedisCacheService implements ICacheService {
// private static instance: ICacheService;

// private redisPool: Pool<Redis>;

// private redLock: Redlock | undefined;

// private constructor() {
// this.redisPool = createPool<Redis>({
// create: async () => new Redis(config.dataSources.redisUrl),
// destroy: (client: Redis) => client.quit().then(() => { }),
// }, {
// max: 200, // maximum size of the pool
// min: 100, // minimum size of the pool
// // additional pool configuration options
// });
// }

// getRedLock(): Redlock | undefined {
// if (this.redLock) return this.redLock;
// return undefined;
// }

// async unlockRedLock(redisLock: Lock) {
// try {
// if (redisLock && this.redLock) {
// await this.redLock.release(redisLock);
// } else {
// log.error('Redlock not initialized');
// }
// } catch (error) {
// log.error(`Error in unlocking redis lock ${JSON.stringify(error)}`);
// }
// }

// public static getInstance(): ICacheService {
// if (!RedisCacheService.instance) {
// RedisCacheService.instance = new RedisCacheService();
// }
// return RedisCacheService.instance;
// }

// async connect(): Promise<void> {
// try {
// const client = await this.redisPool.acquire();
// log.info(`Redis connection status: ${client.status}`);
// await this.redisPool.release(client);
// } catch (error) {
// log.error(`Error in connecting to redis client ${error}`);
// throw error;
// }
// }

// async close(): Promise<void> {
// await this.redisPool.drain();
// await this.redisPool.clear();
// }

// async get(key: string): Promise<string> {
// const client = await this.redisPool.acquire();
// try {
// return await client.get(key) || '';
// } catch (error) {
// log.error(`Error getting value for key ${key} - ${JSON.stringify(error)}`);
// return '';
// } finally {
// await this.redisPool.release(client);
// }
// }

// async set(key: string, value: string, hideValueInLogs: boolean = false): Promise<boolean> {
// const client = await this.redisPool.acquire();
// try {
// if (!hideValueInLogs) {
// log.info(`Setting cache value => Key: ${key} Value: ${value}`);
// } else {
// log.info(`Setting value in cache with key: ${key}`);
// }
// await client.set(key, value);
// log.info(`Cache value set for key: ${key}`);
// return true;
// } catch (error) {
// log.error(`Error setting value for key ${key} - ${JSON.stringify(error)}`);
// return false;
// } finally {
// await this.redisPool.release(client);
// }
// }

// async increment(key: string, incrementBy: number = 1): Promise<boolean> {
// const client = await this.redisPool.acquire();
// try {
// const val = await client.get(key);
// if (!val) {
// log.info('Key does not exist. Nothing to increment');
// return false;
// }
// await client.incrby(key, incrementBy);
// return true;
// } catch (error) {
// log.error(`Error in increment value - ${JSON.stringify(error)}`);
// return false;
// } finally {
// await this.redisPool.release(client);
// }
// }

// async decrement(key: string, decrementBy: number = 1): Promise<boolean> {
// const client = await this.redisPool.acquire();
// try {
// const val = await client.get(key);
// if (val == null || val === 'undefined') {
// log.info('Key does not exist. Nothing to decrement');
// return false;
// }
// await client.decrby(key, decrementBy);
// return true;
// } catch (error) {
// log.error(`Error in decrement value ${JSON.stringify(error)}`);
// return false;
// } finally {
// await this.redisPool.release(client);
// }
// }

// async delete(key: string): Promise<boolean> {
// const client = await this.redisPool.acquire();
// try {
// const result = await client.del(key);
// return result === 1;
// } catch (error) {
// log.error(`Error in deleting key ${key} - ${JSON.stringify(error)}`);
// return false;
// } finally {
// await this.redisPool.release(client);
// }
// }

// async expire(key: string, expiryTime: number): Promise<boolean> {
// const client = await this.redisPool.acquire();
// try {
// const result = await client.expire(key, expiryTime);
// return result === 1;
// } catch (error) {
// log.error(`Error setting expiry for key ${key} - ${JSON.stringify(error)}`);
// return false;
// } finally {
// await this.redisPool.release(client);
// }
// }
// }
Loading

0 comments on commit 92ed307

Please sign in to comment.