Commit ba2aac34 authored by Maurelian's avatar Maurelian Committed by Kelvin Fichter

refactor(contracts): Add deploy step to wait for ownership transfer

parent 3c7d3ace
...@@ -11,10 +11,10 @@ contract AddressSetter { ...@@ -11,10 +11,10 @@ contract AddressSetter {
* Variables * * Variables *
*************/ *************/
Lib_AddressManager manager; Lib_AddressManager public manager;
address finalOwner; address public finalOwner;
string[] names; string[] public names;
address[] addresses; address[] public addresses;
/*************** /***************
* Constructor * * Constructor *
...@@ -64,4 +64,16 @@ contract AddressSetter { ...@@ -64,4 +64,16 @@ contract AddressSetter {
function returnOwnership() external { function returnOwnership() external {
manager.transferOwnership(finalOwner); manager.transferOwnership(finalOwner);
} }
/******************
* View Functions *
******************/
function getNames() external view returns (string[] memory) {
return names;
}
function getAddresses() external view returns (address[] memory) {
return addresses;
}
} }
/* Imports: External */ /* Imports: External */
import { hexStringEquals } from '@eth-optimism/core-utils'
import { DeployFunction } from 'hardhat-deploy/dist/types' import { DeployFunction } from 'hardhat-deploy/dist/types'
/* Imports: Internal */ /* Imports: Internal */
import { getDeployedContract } from '../src/hardhat-deploy-ethers' import {
getDeployedContract,
getReusableContract,
waitUntilTrue,
} from '../src/hardhat-deploy-ethers'
const deployFn: DeployFunction = async (hre) => { const deployFn: DeployFunction = async (hre) => {
// todo: add waitUntilTrue, detect when AddressSetter1 has ownership of the AddressManager const addressSetter1 = await getDeployedContract(hre, 'AddressSetter1')
await (await getDeployedContract(hre, 'AddressSetter1')).setAddresses() const libAddressManager = await getReusableContract(hre, 'Lib_AddressManager')
const names = await addressSetter1.getNames()
const addresses = await addressSetter1.getAddresses()
const finalOwner = await addressSetter1.finalOwner()
console.log(
'\n',
'An Address Setter contract has been deployed, with the following address <=> name pairs:'
)
for (let i = 0; i < names.length; i++) {
console.log(`${addresses[i]} <=> ${names[i]}`)
}
console.log(
'\n',
'Please verify the values above, and the deployment steps up to this point,'
)
console.log(
` then transfer ownership of the Address Manager at (${libAddressManager.address})`
)
console.log(` to the Address Setter contract at ${addressSetter1.address}.`)
await waitUntilTrue(
async () => {
console.log('Checking ownership of Lib_AddressManager')
return hexStringEquals(
await libAddressManager.owner(),
addressSetter1.address
)
},
{
// Try every 30 seconds for 500 minutes.
delay: 30_000,
retries: 1000,
}
)
// Set the addresses!
await addressSetter1.setAddresses()
const currentOwner = await libAddressManager.owner()
console.log('Verifying final ownership of Lib_AddressManager')
if (!hexStringEquals(finalOwner, currentOwner)) {
// todo: pause here get user input deciding whether to continue or exit?
console.log(
`The current address manager owner ${currentOwner}, \nis not equal to the expected owner: ${finalOwner}`
)
}
} }
deployFn.tags = ['set-addresses', 'upgrade'] deployFn.tags = ['set-addresses', 'upgrade']
......
/* Imports: External */ /* Imports: External */
import { hexStringEquals } from '@eth-optimism/core-utils'
import { DeployFunction } from 'hardhat-deploy/dist/types' import { DeployFunction } from 'hardhat-deploy/dist/types'
/* Imports: Internal */ /* Imports: Internal */
import { import {
registerAddress,
getDeployedContract, getDeployedContract,
getReusableContract,
waitUntilTrue,
} from '../src/hardhat-deploy-ethers' } from '../src/hardhat-deploy-ethers'
import { predeploys } from '../src/predeploys'
// todo: reduce redundancy between this and 071
const deployFn: DeployFunction = async (hre) => { const deployFn: DeployFunction = async (hre) => {
// L2CrossDomainMessenger is the address of the predeploy on L2. We can refactor off-chain const addressSetter2 = await getDeployedContract(hre, 'AddressSetter2')
// services such that we can remove the need to set this address, but for now it's easier const libAddressManager = await getReusableContract(hre, 'Lib_AddressManager')
// to simply keep setting the address. const names = await addressSetter2.getNames()
// OVM_Sequencer is the address allowed to submit "Sequencer" blocks to the const addresses = await addressSetter2.getAddresses()
// CanonicalTransactionChain. const finalOwner = await addressSetter2.finalOwner()
// OVM_Proposer is the address allowed to submit state roots (transaction results) to the
// StateCommitmentChain. console.log(
const names = [ 'An Address Setter contract has been deployed, with the following address <=> name pairs:'
'ChainStorageContainer-CTC-batches', )
'ChainStorageContainer-SCC-batches', for (let i = 0; i < names.length; i++) {
'CanonicalTransactionChain', console.log(`${addresses[i]} <=> ${names[i]}`)
'StateCommitmentChain', }
'BondManager', console.log(
'OVM_L1CrossDomainMessenger', '\n',
'Proxy__L1CrossDomainMessenger', 'Please verify the values above, and the deployment steps up to this point,'
'Proxy__L1StandardBridge',
]
await Promise.all(
names.map(async (name) => {
const address = (await getDeployedContract(hre, name)).address
await registerAddress({ hre, name, address })
})
) )
console.log(
` then transfer ownership of the Address Manager at (${libAddressManager.address})`
)
console.log(` to the Address Setter contract at ${addressSetter2.address}.`)
await waitUntilTrue(
async () => {
console.log('Checking ownership of Lib_AddressManager')
return hexStringEquals(
await libAddressManager.owner(),
addressSetter2.address
)
},
{
// Try every 30 seconds for 500 minutes.
delay: 30_000,
retries: 1000,
}
)
// Set the addresses!
await addressSetter2.setAddresses()
const currentOwner = await libAddressManager.owner()
console.log('Verifying final ownership of Lib_AddressManager')
if (!hexStringEquals(finalOwner, currentOwner)) {
// todo: pause here get user input deciding whether to continue or exit?
console.log(
`The current address manager owner ${currentOwner}, \nis not equal to the expected owner: ${finalOwner}`
)
}
} }
deployFn.tags = ['set-addresses', 'upgrade'] deployFn.tags = ['set-addresses', 'upgrade']
......
...@@ -118,16 +118,19 @@ task('deploy') ...@@ -118,16 +118,19 @@ task('deploy')
validateAddressArg('ovmProposerAddress') validateAddressArg('ovmProposerAddress')
validateAddressArg('ovmAddressManagerOwner') validateAddressArg('ovmAddressManagerOwner')
// validate potentially conflicting arguments // Validate potentially conflicting arguments
// When are argName is provided, it indicates an address that will be reused in this deployment.
// When a tagName is provided, it indicates that a new contract will be deployed.
const validateArgOrTag = (argName: string, tagName: string) => { const validateArgOrTag = (argName: string, tagName: string) => {
// ensure that both an arg and tag were not provided for a given contract // The 'fresh' tag tells us that a new copy of each contract will be deployed.
const hasTag = args.tags.includes(tagName) const hasTag = args.tags.includes('fresh') || args.tags.includes(tagName)
// Ensure that an arg and tag were NOT BOTH provided for a given contract
if (hasTag && ethers.utils.isAddress(args[argName])) { if (hasTag && ethers.utils.isAddress(args[argName])) {
throw new Error( throw new Error(
`cannot deploy a new ${tagName} if the address of an existing one is provided` `cannot deploy a new ${tagName} if the address of an existing one is provided`
) )
} }
// ensure that either a valid address is provided or we'll deploy a new one. // Ensure that either a valid address is provided OR that we deploy a new one.
try { try {
validateAddressArg(argName) validateAddressArg(argName)
console.log( console.log(
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment