From aa9ee61712cfa91eeae30618d2dd64291dc669f1 Mon Sep 17 00:00:00 2001 From: Dmytro Stebaiev Date: Wed, 10 Jul 2024 18:33:55 +0300 Subject: [PATCH] Fix nonce issue --- src/nonceProvider.ts | 24 +++++++++++++++++++++--- src/upgrader.ts | 21 ++++++++++++++++----- 2 files changed, 37 insertions(+), 8 deletions(-) diff --git a/src/nonceProvider.ts b/src/nonceProvider.ts index 3aa7a5b..23cd546 100644 --- a/src/nonceProvider.ts +++ b/src/nonceProvider.ts @@ -2,9 +2,11 @@ import {Signer} from "ethers"; export class NonceProvider { currentNonce: number; + releasedNonces: number[]; constructor (nonce: number) { this.currentNonce = nonce; + this.releasedNonces = []; } static async createForWallet (signer: Signer) { @@ -12,8 +14,24 @@ export class NonceProvider { } reserveNonce () { - const nonce = this.currentNonce; - this.currentNonce += 1; - return nonce; + if (!this.releasedNonces) { + const nonce = this.currentNonce; + this.currentNonce += 1; + return nonce; + } + return this.releasedNonces.shift(); + } + + releaseNonce (nonce: number) { + if (NonceProvider.next(nonce) === this.currentNonce) { + this.currentNonce -= 1; + } else { + this.releasedNonces.push(nonce); + } + } + + private static next (nonce: number) { + const nextDiff = 1; + return nonce + nextDiff; } } diff --git a/src/upgrader.ts b/src/upgrader.ts index 8105f39..f5496f4 100644 --- a/src/upgrader.ts +++ b/src/upgrader.ts @@ -1,3 +1,4 @@ +import {ContractFactory, Transaction} from "ethers"; import {Manifest, getImplementationAddress} from "@openzeppelin/upgrades-core"; import {ethers, network, upgrades} from "hardhat"; import {AutoSubmitter} from "./submitters/auto-submitter"; @@ -7,7 +8,6 @@ import {NonceProvider} from "./nonceProvider"; import {ProxyAdmin} from "../typechain-types"; import Semaphore from 'semaphore-async-await'; import {Submitter} from "./submitters/submitter"; -import {Transaction} from "ethers"; import chalk from "chalk"; import {promises as fs} from "fs"; import {getContractFactoryAndUpdateManifest} from "./contractFactory"; @@ -31,7 +31,7 @@ interface Project { const withoutNull = (array: Array) => array. filter((element) => element !== null) as Array; -const maxSimultaneousDeployments = 5; +const maxSimultaneousDeployments = 8; // 10 minutes const deployTimeout = 60e4; @@ -221,17 +221,25 @@ export abstract class Upgrader { (await this.instance.getContract(contract)).getAddress(); console.log(`Prepare upgrade of ${contract}`); + + return this.prepareUpgrade(contract, proxyAddress, contractFactory); + } + + private async prepareUpgrade(contractName: string, proxyAddress: string, contractFactory: ContractFactory) { const currentImplementationAddress = await getImplementationAddress( network.provider, proxyAddress ); + + const nonce = this.nonceProvider?.reserveNonce(); + const newImplementationAddress = await upgrades.prepareUpgrade( proxyAddress, contractFactory, { "timeout": deployTimeout, "txOverrides": { - "nonce": this.nonceProvider?.reserveNonce() + nonce }, "unsafeAllowLinkedLibraries": true, "unsafeAllowRenames": true @@ -240,11 +248,14 @@ export abstract class Upgrader { if (newImplementationAddress !== currentImplementationAddress) { return { "implementationAddress": newImplementationAddress, - "name": contract, + "name": contractName, proxyAddress }; } - console.log(chalk.gray(`Contract ${contract} is up to date`)); + console.log(chalk.gray(`Contract ${contractName} is up to date`)); + if (nonce) { + this.nonceProvider?.releaseNonce(nonce); + } return null; }