mirror of
https://github.com/datahaven-xyz/datahaven
synced 2026-05-24 09:50:01 +00:00
fix: add upgradeAndCall to include new version (gas efficient)
This commit is contained in:
parent
401a9ccfa1
commit
8e46720e49
2 changed files with 63 additions and 81 deletions
|
|
@ -50,6 +50,7 @@ contract DeployImplementation is Script {
|
|||
|
||||
/**
|
||||
* @notice Update ServiceManager proxy to point to new implementation
|
||||
* @dev This is the legacy upgrade method without version update
|
||||
*/
|
||||
function updateServiceManagerProxy() public {
|
||||
console.log("Updating ServiceManager proxy...");
|
||||
|
|
@ -70,4 +71,35 @@ contract DeployImplementation is Script {
|
|||
|
||||
console.log("ServiceManager proxy updated to new implementation:", newImplementation);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Update ServiceManager proxy and set version in one transaction
|
||||
* @dev Uses upgradeAndCall to combine upgrade and version update, saving gas
|
||||
*/
|
||||
function updateServiceManagerProxyWithVersion() public {
|
||||
console.log("Updating ServiceManager proxy with version...");
|
||||
|
||||
// Get addresses and version from environment variables
|
||||
address serviceManager = vm.envAddress("SERVICE_MANAGER");
|
||||
address newImplementation = vm.envAddress("SERVICE_MANAGER_IMPL");
|
||||
address proxyAdmin = vm.envAddress("PROXY_ADMIN");
|
||||
string memory newVersion = vm.envString("NEW_VERSION");
|
||||
|
||||
require(serviceManager != address(0), "SERVICE_MANAGER not set");
|
||||
require(newImplementation != address(0), "SERVICE_MANAGER_IMPL not set");
|
||||
require(newImplementation.code.length > 0, "SERVICE_MANAGER_IMPL is not a contract");
|
||||
require(proxyAdmin != address(0), "PROXY_ADMIN not set");
|
||||
require(bytes(newVersion).length > 0, "NEW_VERSION not set");
|
||||
|
||||
// Encode the updateVersion call
|
||||
bytes memory data = abi.encodeWithSignature("updateVersion(string)", newVersion);
|
||||
|
||||
vm.broadcast();
|
||||
ProxyAdmin(proxyAdmin).upgradeAndCall(
|
||||
ITransparentUpgradeableProxy(payable(serviceManager)), newImplementation, data
|
||||
);
|
||||
|
||||
console.log("ServiceManager proxy updated to:", newImplementation);
|
||||
console.log("Version updated to:", newVersion);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -133,16 +133,18 @@ export const contractsUpgrade = async (options: ContractsUpgradeOptions) => {
|
|||
privateKey
|
||||
);
|
||||
|
||||
// Update proxy contracts to point to new implementations
|
||||
await updateProxyContracts(options.chain, rpcUrl, privateKey, serviceManagerImplAddress);
|
||||
// Update proxy contracts to point to new implementations AND update version in one transaction
|
||||
await updateProxyContracts(
|
||||
options.chain,
|
||||
rpcUrl,
|
||||
privateKey,
|
||||
serviceManagerImplAddress,
|
||||
targetVersion
|
||||
);
|
||||
|
||||
// Update versions-matrix.json with deployment info
|
||||
await updateVersionsMatrix(options.chain, targetVersion);
|
||||
|
||||
// Update on-chain version to match target version (uses deployer/version updater key)
|
||||
const versionUpdaterKey = resolveVersionUpdaterKey();
|
||||
await updateOnChainVersion(options.chain, rpcUrl, versionUpdaterKey, targetVersion);
|
||||
|
||||
// Verify contracts if requested
|
||||
if (options.verify) {
|
||||
logger.info("🔍 Verifying upgraded contracts...");
|
||||
|
|
@ -256,34 +258,43 @@ const deployServiceManagerImplementation = async (
|
|||
};
|
||||
|
||||
/**
|
||||
* Updates proxy contracts to point to new implementations
|
||||
* Updates proxy contracts to point to new implementations and sets version
|
||||
*/
|
||||
const updateProxyContracts = async (
|
||||
chain: string,
|
||||
rpcUrl: string,
|
||||
privateKey: string,
|
||||
serviceManagerImplAddress: string
|
||||
serviceManagerImplAddress: string,
|
||||
version: string
|
||||
) => {
|
||||
logger.info("🔄 Updating proxy contracts...");
|
||||
logger.info("🔄 Updating proxy contracts and version...");
|
||||
|
||||
const deployments = await parseDeploymentsFile(chain);
|
||||
|
||||
// Update ServiceManager proxy to point to new implementation
|
||||
await updateServiceManagerProxy(deployments, rpcUrl, privateKey, serviceManagerImplAddress);
|
||||
// Update ServiceManager proxy to point to new implementation and update version in one transaction
|
||||
await updateServiceManagerProxyWithVersion(
|
||||
deployments,
|
||||
rpcUrl,
|
||||
privateKey,
|
||||
serviceManagerImplAddress,
|
||||
version
|
||||
);
|
||||
|
||||
logger.success("Proxy contracts updated successfully");
|
||||
logger.success("Proxy contracts updated and version set successfully");
|
||||
};
|
||||
|
||||
/**
|
||||
* Updates ServiceManager proxy to point to new implementation
|
||||
* Updates ServiceManager proxy to point to new implementation and updates version in one transaction
|
||||
* This saves gas by combining upgrade and version update
|
||||
*/
|
||||
const updateServiceManagerProxy = async (
|
||||
const updateServiceManagerProxyWithVersion = async (
|
||||
deployments: any,
|
||||
rpcUrl: string,
|
||||
privateKey: string,
|
||||
serviceManagerImplAddress: string
|
||||
serviceManagerImplAddress: string,
|
||||
version: string
|
||||
) => {
|
||||
logger.info("🔄 Updating ServiceManager proxy...");
|
||||
logger.info(`🔄 Updating ServiceManager proxy and setting version to ${version}...`);
|
||||
|
||||
// Note: Private key is passed via environment variable as required by forge
|
||||
// This is a known limitation of the forge toolchain
|
||||
|
|
@ -300,14 +311,15 @@ const updateServiceManagerProxy = async (
|
|||
RPC_URL: rpcUrl,
|
||||
SERVICE_MANAGER: deployments.ServiceManager,
|
||||
SERVICE_MANAGER_IMPL: serviceManagerImplAddress,
|
||||
PROXY_ADMIN: proxyAdmin
|
||||
PROXY_ADMIN: proxyAdmin,
|
||||
NEW_VERSION: version
|
||||
};
|
||||
|
||||
const updateArgs = [
|
||||
"script",
|
||||
"script/deploy/DeployImplementation.s.sol:DeployImplementation",
|
||||
"--sig",
|
||||
"updateServiceManagerProxy()",
|
||||
"updateServiceManagerProxyWithVersion()",
|
||||
"--rpc-url",
|
||||
rpcUrl,
|
||||
"--private-key",
|
||||
|
|
@ -319,7 +331,7 @@ const updateServiceManagerProxy = async (
|
|||
try {
|
||||
const result = await executeCommand("forge", updateArgs, env, "../contracts");
|
||||
|
||||
logger.success("ServiceManager proxy updated successfully");
|
||||
logger.success(`ServiceManager proxy updated and version set to ${version}`);
|
||||
logger.debug(result);
|
||||
} catch (error) {
|
||||
logger.error(`❌ Failed to update ServiceManager proxy: ${error}`);
|
||||
|
|
@ -410,65 +422,3 @@ const updateVersionsMatrix = async (chain: string, version: string): Promise<voi
|
|||
logger.info(`📝 Updated versions-matrix.json for chain ${chain}`);
|
||||
};
|
||||
|
||||
/**
|
||||
* Resolves the private key for updating the on-chain version
|
||||
* Uses DEPLOYER_PRIVATE_KEY (version updater) or falls back to PRIVATE_KEY
|
||||
*/
|
||||
const resolveVersionUpdaterKey = (): string => {
|
||||
if (process.env.DEPLOYER_PRIVATE_KEY) {
|
||||
return process.env.DEPLOYER_PRIVATE_KEY;
|
||||
}
|
||||
if (process.env.PRIVATE_KEY) {
|
||||
return process.env.PRIVATE_KEY;
|
||||
}
|
||||
throw new Error(
|
||||
"Private key is required for version update. Set DEPLOYER_PRIVATE_KEY or PRIVATE_KEY environment variable"
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Updates the on-chain version by calling updateVersion() on the ServiceManager
|
||||
*/
|
||||
const updateOnChainVersion = async (
|
||||
chain: string,
|
||||
rpcUrl: string,
|
||||
privateKey: string,
|
||||
version: string
|
||||
): Promise<void> => {
|
||||
logger.info(`📝 Updating on-chain version to ${version}...`);
|
||||
|
||||
try {
|
||||
const deployments = await parseDeploymentsFile(chain);
|
||||
const serviceManagerAddress = (deployments as any).ServiceManager;
|
||||
|
||||
if (!serviceManagerAddress) {
|
||||
throw new Error("ServiceManager address not found in deployment file");
|
||||
}
|
||||
|
||||
// Use cast to call updateVersion on the ServiceManager
|
||||
const args = [
|
||||
"send",
|
||||
serviceManagerAddress,
|
||||
"updateVersion(string)",
|
||||
version,
|
||||
"--rpc-url",
|
||||
rpcUrl,
|
||||
"--private-key",
|
||||
privateKey
|
||||
];
|
||||
|
||||
const env: Record<string, string> = {};
|
||||
// Only copy defined env vars
|
||||
for (const [key, value] of Object.entries(process.env)) {
|
||||
if (value !== undefined) {
|
||||
env[key] = value;
|
||||
}
|
||||
}
|
||||
await executeCommand("cast", args, env, "../contracts");
|
||||
|
||||
logger.success(`On-chain version updated to ${version}`);
|
||||
} catch (error) {
|
||||
logger.error(`❌ Failed to update on-chain version: ${error}`);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue