From de610175528f0037ff0d5ef1113602f05e45e902 Mon Sep 17 00:00:00 2001 From: EvgenKor Date: Wed, 4 Sep 2024 01:40:53 +0300 Subject: [PATCH] Adding index to local cache --- zp-relayer/pool/RelayPool.ts | 8 ++++---- zp-relayer/state/TxStore.ts | 28 ++++++++++++++++++++++------ zp-relayer/utils/helpers.ts | 10 +++++++++- 3 files changed, 35 insertions(+), 11 deletions(-) diff --git a/zp-relayer/pool/RelayPool.ts b/zp-relayer/pool/RelayPool.ts index 0c9268b..6e38b02 100644 --- a/zp-relayer/pool/RelayPool.ts +++ b/zp-relayer/pool/RelayPool.ts @@ -262,7 +262,7 @@ export class RelayPool extends BasePool { } // cache transaction locally - await this.cacheTxLocally(outCommit, txHash, memo); + await this.cacheTxLocally(outCommit, txHash, memo, commitIndex); // start monitoring local cache against the indexer to cleanup already indexed txs this.startLocalCacheObserver(commitIndex); } @@ -278,7 +278,7 @@ export class RelayPool extends BasePool { poolJob.data.transaction.txHash = txHash; await poolJob.update(poolJob.data); - await this.cacheTxLocally(res.outCommit, txHash, res.memo); + await this.cacheTxLocally(res.outCommit, txHash, res.memo, res.commitIndex); } } } @@ -296,7 +296,7 @@ export class RelayPool extends BasePool { } } - protected async cacheTxLocally(commit: string, txHash: string, memo: string) { + protected async cacheTxLocally(commit: string, txHash: string, memo: string, index: number) { // store or updating local tx store // (we should keep sent transaction until the indexer grab them) const prefixedMemo = buildPrefixedMemo( @@ -304,7 +304,7 @@ export class RelayPool extends BasePool { txHash, memo ); - await this.txStore.add(commit, prefixedMemo); + await this.txStore.add(commit, prefixedMemo, index); logger.info(`Tx with commit ${commit} has been CACHED locally`); } diff --git a/zp-relayer/state/TxStore.ts b/zp-relayer/state/TxStore.ts index 6fce219..c3d6b3c 100644 --- a/zp-relayer/state/TxStore.ts +++ b/zp-relayer/state/TxStore.ts @@ -1,23 +1,39 @@ +import { hexToNumber, numberToHexPadded } from '@/utils/helpers'; import type { Redis } from 'ioredis' +const INDEX_BYTES = 6; + export class TxStore { constructor(public name: string, private redis: Redis) {} - async add(commitment: string, memo: string) { - await this.redis.hset(this.name, { [commitment]: memo }) + async add(commitment: string, memo: string, index: number) { + await this.redis.hset(this.name, { [commitment]: `${numberToHexPadded(index, INDEX_BYTES)}${memo}` }) } async remove(commitment: string) { await this.redis.hdel(this.name, commitment) } - async get(commitment: string) { - const memo = await this.redis.hget(this.name, commitment) - return memo + async get(commitment: string): Promise<{memo: string, index: number} | null> { + const data = await this.redis.hget(this.name, commitment); + + return data ? { + memo: data.slice(INDEX_BYTES * 2), + index: hexToNumber(data.slice(0, INDEX_BYTES * 2)), + } : null; } async getAll() { - return await this.redis.hgetall(this.name) + return await this.redis.hgetall(this.name).then(keys => { + return Object.entries(keys) + .map(([commit, data]) => + [commit, + { + memo: data.slice(INDEX_BYTES * 2), + index: hexToNumber(data.slice(0, INDEX_BYTES * 2)), + }] as [string, {memo: string, index: number}] + ) + } } async removeAll() { diff --git a/zp-relayer/utils/helpers.ts b/zp-relayer/utils/helpers.ts index 4d6f336..d969c7c 100644 --- a/zp-relayer/utils/helpers.ts +++ b/zp-relayer/utils/helpers.ts @@ -8,7 +8,7 @@ import type { SnarkProof } from 'libzkbob-rs-node' import promiseRetry from 'promise-retry' import type Web3 from 'web3' import type { Contract } from 'web3-eth-contract' -import { padLeft, toBN } from 'web3-utils' +import { padLeft, toBN, numberToHex } from 'web3-utils' import { TxType } from 'zp-memo-parser' import { isContractCallError } from './web3Errors' @@ -316,3 +316,11 @@ export async function fetchJson(serverUrl: string, path: string, query: [string, return await res.json() } + +export function numberToHexPadded(num: number, numBytes: number): string { + return padLeft(numberToHex(num).slice(2), numBytes * 2); +} + +export function hexToNumber(hex: string): number { + return parseInt(hex, 16); +} \ No newline at end of file