Skip to content

Commit 3c20163

Browse files
authored
Fk/extend ph worker (#595)
* Update: Added nonce rebase with blockchain logic * removed logs * updates
1 parent 4ff53a8 commit 3c20163

File tree

2 files changed

+44
-3
lines changed

2 files changed

+44
-3
lines changed

src/db/wallets/walletNonce.ts

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { thirdwebClient } from "../../utils/sdk";
88
* The "last used nonce" stores the last nonce submitted onchain.
99
* Example: "25"
1010
*/
11-
const lastUsedNonceKey = (chainId: number, walletAddress: Address) =>
11+
export const lastUsedNonceKey = (chainId: number, walletAddress: Address) =>
1212
`nonce:${chainId}:${normalizeAddress(walletAddress)}`;
1313

1414
/**
@@ -122,3 +122,36 @@ export const deleteAllNonces = async () => {
122122
await redis.del(keys);
123123
}
124124
};
125+
126+
/**
127+
* Resync the nonce i.e., max of transactionCount +1 and lastUsedNonce.
128+
* @param chainId
129+
* @param walletAddress
130+
*/
131+
export const rebaseNonce = async (chainId: number, walletAddress: Address) => {
132+
const rpcRequest = getRpcClient({
133+
client: thirdwebClient,
134+
chain: await getChain(chainId),
135+
});
136+
137+
// The next unused nonce = transactionCount.
138+
const transactionCount = await eth_getTransactionCount(rpcRequest, {
139+
address: walletAddress,
140+
});
141+
142+
// Lua script to set nonce as max(transactionCount, redis.get(lastUsedNonceKey))
143+
const script = `
144+
local transactionCount = tonumber(ARGV[1])
145+
local lastUsedNonce = tonumber(redis.call('get', KEYS[1]))
146+
local nextNonce = math.max(transactionCount, lastUsedNonce)
147+
redis.call('set', KEYS[1], nextNonce)
148+
return nextNonce
149+
`;
150+
const nextNonce = await redis.eval(
151+
script,
152+
1,
153+
lastUsedNonceKey(chainId, normalizeAddress(walletAddress)),
154+
transactionCount.toString(),
155+
);
156+
return nextNonce;
157+
};

src/worker/tasks/sendTransactionWorker.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,11 @@ import { bundleUserOp } from "thirdweb/wallets/smart";
77
import type { TransactionSerializable } from "viem";
88
import { getContractAddress } from "viem";
99
import { TransactionDB } from "../../db/transactions/db";
10-
import { acquireNonce, recycleNonce } from "../../db/wallets/walletNonce";
10+
import {
11+
acquireNonce,
12+
rebaseNonce,
13+
recycleNonce,
14+
} from "../../db/wallets/walletNonce";
1115
import { getAccount } from "../../utils/account";
1216
import { getBlockNumberish } from "../../utils/block";
1317
import { getChain } from "../../utils/chain";
@@ -167,7 +171,11 @@ const _sendTransaction = async (
167171
transactionHash = sendTransactionResult.transactionHash;
168172
job.log(`Sent transaction: ${transactionHash}`);
169173
} catch (error: unknown) {
170-
if (!isNonceAlreadyUsedError(error)) {
174+
// If NonceAlreadyUsedError, rebase the nonce and retry.
175+
if (isNonceAlreadyUsedError(error)) {
176+
const resyncNonce = await rebaseNonce(chainId, from);
177+
job.log(`Resynced nonce to ${resyncNonce}.`);
178+
} else {
171179
job.log(`Recycling nonce: ${nonce}`);
172180
await recycleNonce(chainId, from, nonce);
173181
}

0 commit comments

Comments
 (0)