Skip to content

Commit e5aa190

Browse files
committed
feat: speed up scratch deployment for local-devnet
1 parent 483b442 commit e5aa190

8 files changed

+239
-151
lines changed

lib/deploy.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { LidoLocator } from "typechain-types";
66

77
import { addContractHelperFields, DeployedContract, getContractPath, loadContract, LoadedContract } from "lib/contract";
88
import { ConvertibleToString, cy, gr, log, yl } from "lib/log";
9+
import { getNonceManagerWithDeployer } from "lib/nonce-manager";
910
import { incrementGasUsed, Sk, updateObjectInState } from "lib/state-file";
1011

1112
const GAS_PRIORITY_FEE = process.env.GAS_PRIORITY_FEE || null;
@@ -33,9 +34,11 @@ export async function makeTx(
3334
txParams: TxParams,
3435
withStateFile = true,
3536
): Promise<ContractTransactionReceipt> {
37+
const contractWithNonceManager = contract.connect(await getNonceManagerWithDeployer());
38+
3639
log.withArguments(`Call: ${yl(contract.name)}[${cy(contract.address)}].${yl(funcName)}`, args);
3740

38-
const tx = await contract.getFunction(funcName)(...args, txParams);
41+
const tx = await contractWithNonceManager.getFunction(funcName)(...args, txParams);
3942
log(` Transaction: ${tx.hash} (nonce ${yl(tx.nonce)})...`);
4043

4144
const receipt = await tx.wait();
@@ -74,7 +77,9 @@ async function deployContractType2(
7477
): Promise<DeployedContract> {
7578
const txParams = await getDeployTxParams(deployer);
7679
const factory = (await ethers.getContractFactory(artifactName, signerOrOptions)) as ContractFactory;
77-
const contract = await factory.deploy(...constructorArgs, txParams);
80+
const factoryWithNonceManager = factory.connect(await getNonceManagerWithDeployer());
81+
82+
const contract = await factoryWithNonceManager.deploy(...constructorArgs, txParams);
7883
const tx = contract.deploymentTransaction();
7984
if (!tx) {
8085
throw new Error(`Failed to send the deployment transaction for ${artifactName}`);

lib/nonce-manager.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { NonceManager } from "ethers";
2+
import { ethers } from "hardhat";
3+
4+
let cachedNonceManager: NonceManager;
5+
6+
export const getNonceManagerWithDeployer = async () => {
7+
if (cachedNonceManager) {
8+
return cachedNonceManager;
9+
}
10+
const [deployer] = await ethers.getSigners();
11+
12+
const nonceManager = new ethers.NonceManager(deployer);
13+
cachedNonceManager = nonceManager;
14+
15+
return nonceManager;
16+
};

scripts/scratch/steps/0020-deploy-aragon-env.ts

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -94,27 +94,25 @@ export async function main() {
9494
if (daoFactoryAddress) {
9595
log(`Using pre-deployed DAOFactory: ${cy(state[Sk.daoFactory].address)}`);
9696
} else {
97-
const kernelBase = await deployImplementation(Sk.aragonKernel, "Kernel", deployer, [true]);
98-
const aclBase = await deployImplementation(Sk.aragonAcl, "ACL", deployer);
99-
const evmScriptRegistryFactory = await deployWithoutProxy(
100-
Sk.evmScriptRegistryFactory,
101-
"EVMScriptRegistryFactory",
102-
deployer,
103-
);
97+
const [kernelBase, aclBase, evmScriptRegistryFactory] = await Promise.all([
98+
deployImplementation(Sk.aragonKernel, "Kernel", deployer, [true]),
99+
deployImplementation(Sk.aragonAcl, "ACL", deployer),
100+
deployWithoutProxy(Sk.evmScriptRegistryFactory, "EVMScriptRegistryFactory", deployer),
101+
]);
102+
104103
const daoFactoryArgs = [kernelBase.address, aclBase.address, evmScriptRegistryFactory.address];
105104
daoFactoryAddress = (await deployWithoutProxy(Sk.daoFactory, "DAOFactory", deployer, daoFactoryArgs)).address;
106105
}
107106
const daoFactory = await loadContract<DAOFactory>("DAOFactory", daoFactoryAddress);
108107

109108
// Deploy APM registry factory
110109
log.header(`APM registry factory`);
111-
const apmRegistryBase = await deployImplementation(Sk.aragonApmRegistry, "APMRegistry", deployer);
112-
const apmRepoBase = await deployWithoutProxy(Sk.aragonRepoBase, "Repo", deployer);
113-
const ensSubdomainRegistrarBase = await deployImplementation(
114-
Sk.ensSubdomainRegistrar,
115-
"ENSSubdomainRegistrar",
116-
deployer,
117-
);
110+
const [apmRegistryBase, apmRepoBase, ensSubdomainRegistrarBase] = await Promise.all([
111+
deployImplementation(Sk.aragonApmRegistry, "APMRegistry", deployer),
112+
deployWithoutProxy(Sk.aragonRepoBase, "Repo", deployer),
113+
deployImplementation(Sk.ensSubdomainRegistrar, "ENSSubdomainRegistrar", deployer),
114+
]);
115+
118116

119117
const apmRegistryFactory = await deployWithoutProxy(Sk.apmRegistryFactory, "APMRegistryFactory", deployer, [
120118
daoFactory.address,

scripts/scratch/steps/0030-deploy-template-and-app-bases.ts

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,16 @@ export async function main() {
77
const deployer = (await ethers.provider.getSigner()).address;
88
const state = readNetworkState({ deployer });
99

10-
// Deploy Aragon app implementations
11-
await deployImplementation(Sk.appAgent, "Agent", deployer);
12-
await deployImplementation(Sk.appFinance, "Finance", deployer);
13-
await deployImplementation(Sk.appTokenManager, "TokenManager", deployer);
14-
await deployImplementation(Sk.appVoting, "Voting", deployer);
15-
16-
// Deploy Lido-specific app implementations
17-
await deployImplementation(Sk.appLido, "Lido", deployer);
18-
await deployImplementation(Sk.appOracle, "LegacyOracle", deployer);
10+
await Promise.all([
11+
// Deploy Aragon app implementations
12+
deployImplementation(Sk.appAgent, "Agent", deployer),
13+
deployImplementation(Sk.appFinance, "Finance", deployer),
14+
deployImplementation(Sk.appTokenManager, "TokenManager", deployer),
15+
deployImplementation(Sk.appVoting, "Voting", deployer),
16+
// Deploy Lido-specific app implementations
17+
deployImplementation(Sk.appLido, "Lido", deployer),
18+
deployImplementation(Sk.appOracle, "LegacyOracle", deployer),
19+
]);
1920

2021
const minFirstAllocationStrategy = await deployWithoutProxy(
2122
Sk.minFirstAllocationStrategy,
Lines changed: 83 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { ContractTransactionReceipt } from "ethers";
12
import { ethers } from "hardhat";
23

34
import { loadContract } from "lib/contract";
@@ -36,107 +37,135 @@ export async function main() {
3637
const stakingRouterAdmin = testnetAdmin;
3738
const withdrawalQueueAdmin = testnetAdmin;
3839

40+
const waitTransactionsGroup: Promise<ContractTransactionReceipt>[] = [];
41+
3942
// Initialize NodeOperatorsRegistry
4043

4144
// https://github.com/ethereum/solidity-examples/blob/master/docs/bytes/Bytes.md#description
4245
const encodeStakingModuleTypeId = (stakingModuleTypeId: string): string =>
4346
"0x" + ethers.AbiCoder.defaultAbiCoder().encode(["string"], [stakingModuleTypeId]).slice(-64);
4447

4548
const nodeOperatorsRegistry = await loadContract("NodeOperatorsRegistry", nodeOperatorsRegistryAddress);
46-
await makeTx(
47-
nodeOperatorsRegistry,
48-
"initialize",
49-
[
50-
lidoLocatorAddress,
51-
encodeStakingModuleTypeId(nodeOperatorsRegistryParams.stakingModuleTypeId),
52-
nodeOperatorsRegistryParams.stuckPenaltyDelay,
53-
],
54-
{ from: deployer },
49+
waitTransactionsGroup.push(
50+
makeTx(
51+
nodeOperatorsRegistry,
52+
"initialize",
53+
[
54+
lidoLocatorAddress,
55+
encodeStakingModuleTypeId(nodeOperatorsRegistryParams.stakingModuleTypeId),
56+
nodeOperatorsRegistryParams.stuckPenaltyDelay,
57+
],
58+
{ from: deployer },
59+
),
5560
);
5661

5762
const simpleDvtRegistry = await loadContract("NodeOperatorsRegistry", simpleDvtRegistryAddress);
58-
await makeTx(
59-
simpleDvtRegistry,
60-
"initialize",
61-
[
62-
lidoLocatorAddress,
63-
encodeStakingModuleTypeId(simpleDvtRegistryParams.stakingModuleTypeId),
64-
simpleDvtRegistryParams.stuckPenaltyDelay,
65-
],
66-
{ from: deployer },
63+
waitTransactionsGroup.push(
64+
makeTx(
65+
simpleDvtRegistry,
66+
"initialize",
67+
[
68+
lidoLocatorAddress,
69+
encodeStakingModuleTypeId(simpleDvtRegistryParams.stakingModuleTypeId),
70+
simpleDvtRegistryParams.stuckPenaltyDelay,
71+
],
72+
{ from: deployer },
73+
),
6774
);
6875

6976
// Initialize Lido
7077
const bootstrapInitBalance = 10n; // wei
7178
const lido = await loadContract("Lido", lidoAddress);
72-
await makeTx(lido, "initialize", [lidoLocatorAddress, eip712StETHAddress], {
73-
value: bootstrapInitBalance,
74-
from: deployer,
75-
});
79+
waitTransactionsGroup.push(
80+
makeTx(lido, "initialize", [lidoLocatorAddress, eip712StETHAddress], {
81+
value: bootstrapInitBalance,
82+
from: deployer,
83+
}),
84+
);
7685

7786
// Initialize LegacyOracle
7887
const legacyOracle = await loadContract("LegacyOracle", legacyOracleAddress);
79-
await makeTx(legacyOracle, "initialize", [lidoLocatorAddress, hashConsensusForAccountingAddress], { from: deployer });
88+
waitTransactionsGroup.push(
89+
makeTx(legacyOracle, "initialize", [lidoLocatorAddress, hashConsensusForAccountingAddress], {
90+
from: deployer,
91+
}),
92+
);
8093

8194
const zeroLastProcessingRefSlot = 0;
8295

8396
// Initialize AccountingOracle
8497
const accountingOracle = await loadContract("AccountingOracle", accountingOracleAddress);
85-
await makeTx(
86-
accountingOracle,
87-
"initializeWithoutMigration",
88-
[
89-
accountingOracleAdmin,
90-
hashConsensusForAccountingAddress,
91-
accountingOracleParams.consensusVersion,
92-
zeroLastProcessingRefSlot,
93-
],
94-
{ from: deployer },
98+
waitTransactionsGroup.push(
99+
makeTx(
100+
accountingOracle,
101+
"initializeWithoutMigration",
102+
[
103+
accountingOracleAdmin,
104+
hashConsensusForAccountingAddress,
105+
accountingOracleParams.consensusVersion,
106+
zeroLastProcessingRefSlot,
107+
],
108+
{ from: deployer },
109+
),
95110
);
96111

97112
// Initialize ValidatorsExitBusOracle
98113
const validatorsExitBusOracle = await loadContract("ValidatorsExitBusOracle", ValidatorsExitBusOracleAddress);
99-
await makeTx(
100-
validatorsExitBusOracle,
101-
"initialize",
102-
[
103-
exitBusOracleAdmin,
104-
hashConsensusForValidatorsExitBusOracleAddress,
105-
validatorsExitBusOracleParams.consensusVersion,
106-
zeroLastProcessingRefSlot,
107-
],
108-
{ from: deployer },
114+
waitTransactionsGroup.push(
115+
makeTx(
116+
validatorsExitBusOracle,
117+
"initialize",
118+
[
119+
exitBusOracleAdmin,
120+
hashConsensusForValidatorsExitBusOracleAddress,
121+
validatorsExitBusOracleParams.consensusVersion,
122+
zeroLastProcessingRefSlot,
123+
],
124+
{ from: deployer },
125+
),
109126
);
110127

111128
// Initialize WithdrawalQueue
112129
const withdrawalQueue = await loadContract("WithdrawalQueueERC721", withdrawalQueueAddress);
113-
await makeTx(withdrawalQueue, "initialize", [withdrawalQueueAdmin], { from: deployer });
130+
waitTransactionsGroup.push(makeTx(withdrawalQueue, "initialize", [withdrawalQueueAdmin], { from: deployer }));
114131

115132
// Set WithdrawalQueue base URI if provided
116133
const withdrawalQueueBaseUri = state["withdrawalQueueERC721"].deployParameters.baseUri;
117134
if (withdrawalQueueBaseUri !== null && withdrawalQueueBaseUri !== "") {
118135
const MANAGE_TOKEN_URI_ROLE = await withdrawalQueue.getFunction("MANAGE_TOKEN_URI_ROLE")();
119-
await makeTx(withdrawalQueue, "grantRole", [MANAGE_TOKEN_URI_ROLE, deployer], { from: deployer });
120-
await makeTx(withdrawalQueue, "setBaseURI", [withdrawalQueueBaseUri], { from: deployer });
121-
await makeTx(withdrawalQueue, "renounceRole", [MANAGE_TOKEN_URI_ROLE, deployer], { from: deployer });
136+
waitTransactionsGroup.push(
137+
makeTx(withdrawalQueue, "grantRole", [MANAGE_TOKEN_URI_ROLE, deployer], { from: deployer }),
138+
);
139+
waitTransactionsGroup.push(makeTx(withdrawalQueue, "setBaseURI", [withdrawalQueueBaseUri], { from: deployer }));
140+
waitTransactionsGroup.push(
141+
makeTx(withdrawalQueue, "renounceRole", [MANAGE_TOKEN_URI_ROLE, deployer], { from: deployer }),
142+
);
122143
}
123144

124145
// Initialize StakingRouter
125146
const withdrawalCredentials = `0x010000000000000000000000${withdrawalVaultAddress.slice(2)}`;
126147
const stakingRouter = await loadContract("StakingRouter", stakingRouterAddress);
127-
await makeTx(stakingRouter, "initialize", [stakingRouterAdmin, lidoAddress, withdrawalCredentials], {
128-
from: deployer,
129-
});
148+
waitTransactionsGroup.push(
149+
makeTx(stakingRouter, "initialize", [stakingRouterAdmin, lidoAddress, withdrawalCredentials], {
150+
from: deployer,
151+
}),
152+
);
130153

131154
// Set OracleDaemonConfig parameters
132155
const oracleDaemonConfig = await loadContract("OracleDaemonConfig", oracleDaemonConfigAddress);
133156
const CONFIG_MANAGER_ROLE = await oracleDaemonConfig.getFunction("CONFIG_MANAGER_ROLE")();
134157
await makeTx(oracleDaemonConfig, "grantRole", [CONFIG_MANAGER_ROLE, testnetAdmin], { from: testnetAdmin });
135158

136159
// Set each parameter in the OracleDaemonConfig
137-
for (const [key, value] of Object.entries(state.oracleDaemonConfig.deployParameters)) {
138-
await makeTx(oracleDaemonConfig, "set", [key, en0x(value as number)], { from: deployer });
139-
}
160+
const txPromises = Object.entries(state.oracleDaemonConfig.deployParameters).map(([key, value]) => {
161+
return makeTx(oracleDaemonConfig, "set", [key, en0x(value as number)], { from: deployer });
162+
});
163+
164+
await Promise.all(txPromises);
165+
166+
waitTransactionsGroup.push(
167+
makeTx(oracleDaemonConfig, "renounceRole", [CONFIG_MANAGER_ROLE, testnetAdmin], { from: testnetAdmin }),
168+
);
140169

141-
await makeTx(oracleDaemonConfig, "renounceRole", [CONFIG_MANAGER_ROLE, testnetAdmin], { from: testnetAdmin });
170+
await Promise.all(waitTransactionsGroup);
142171
}

0 commit comments

Comments
 (0)