Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Subnet registry to deploy upgradeable subnet actors #822

Merged
merged 15 commits into from
Mar 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion contracts/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ upgrade-gw-diamond:
./ops/upgrade-gw-diamond.sh $(NETWORK)

upgrade-sa-diamond:
./ops/upgrade-sa-diamond.sh $(NETWORK)
./ops/upgrade-sa-diamond.sh $(NETWORK) $(SUBNET_ACTOR_ADDRESS)

upgrade-sr-diamond:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @snissn, just a quick question for upgrading subnet-registry, if the subnet actor code has updated, and an we want the registry to deploy new version of SubnetActor, after an upgrade of SubnetRegistry, will the registry start deploying the newer version of the Subnet Actor?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey will! The answer should be yes. Using the upgrade code to upgrade src/subnetregistry/RegisterSubnetFacet.sol in the registry should change the deploy path for new subnets.

./ops/upgrade-sr-diamond.sh $(NETWORK)
Expand Down
1 change: 1 addition & 0 deletions contracts/binding/build.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions contracts/binding/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ pub mod lib_staking;
#[allow(clippy::all)]
pub mod lib_staking_change_log;
#[allow(clippy::all)]
pub mod ownership_facet;
#[allow(clippy::all)]
pub mod register_subnet_facet;
#[allow(clippy::all)]
pub mod subnet_actor_checkpointing_facet;
Expand Down
74 changes: 37 additions & 37 deletions contracts/hardhat.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,25 +81,36 @@ async function saveSubnetRegistry(
fs.writeFileSync(subnetRegistryJsonPath, JSON.stringify(subnetRegistryJson))
}

async function saveSubnetActor(
env: string,
subnetRegistryData: { [key in string]: string },
) {
const subnetRegistryJsonPath = `${process.cwd()}/subnet.actor.json`

let subnetRegistryJson = { [env]: {} }
if (fs.existsSync(subnetRegistryJsonPath)) {
subnetRegistryJson = JSON.parse(
fs.readFileSync(subnetRegistryJsonPath).toString(),
async function readSubnetActor(subnetActorAddress, network) {
const subnetActorJsonPath = `${process.cwd()}/subnet.actor-${subnetActorAddress}.json`
if (fs.existsSync(subnetActorJsonPath)) {
const subnetActor = JSON.parse(
fs.readFileSync(subnetActorJsonPath).toString(),
)
return subnetActor
}

subnetRegistryJson[env] = {
...subnetRegistryJson[env],
...subnetRegistryData,
const subnetRegistry = await getSubnetRegistry(network)
const deployments = {
SubnetActorDiamond: subnetActorAddress,
Facets: subnetRegistry.SubnetActorFacets,
}
return deployments
}

fs.writeFileSync(subnetRegistryJsonPath, JSON.stringify(subnetRegistryJson))
async function saveSubnetActor(
deployments,
updatedFacets: { [key in string]: string },
) {
const subnetActorJsonPath = `${process.cwd()}/subnet.actor-${
deployments.SubnetActorDiamond
}.json`
for (const facetIndex in deployments.Facets) {
const facetName = deployments.Facets[facetIndex].name
if (updatedFacets[facetName]) {
deployments.Facets[facetIndex].address = updatedFacets[facetName]
}
}
fs.writeFileSync(subnetActorJsonPath, JSON.stringify(deployments))
}

async function getSubnetRegistry(
Expand Down Expand Up @@ -202,25 +213,6 @@ task(
},
)

task(
'deploy-sa-diamond-and-facets',
'Builds and deploys Subnet Actor diamond and its facets',
async (args, hre: HardhatRuntimeEnvironment) => {
await hre.run('compile')

const network = hre.network.name
const deployments = await getDeployments(network)
const { deployDiamond } = await lazyImport(
'./scripts/deploy-sa-diamond',
)
const subnetActorDiamond = await deployDiamond(
deployments.Gateway,
deployments.libs,
)
await saveSubnetActor(network, subnetActorDiamond)
},
)

task(
'deploy',
'Builds and deploys all contracts on the selected network',
Expand Down Expand Up @@ -291,14 +283,22 @@ task(
async (args, hre: HardhatRuntimeEnvironment) => {
await hre.run('compile')
const network = hre.network.name
const deployments = await getSubnetActor(network)
if (!args.address) {
console.error(
'No address provided. Usage: npx hardhat upgrade-sa-diamond --address 0x80afa...',
)
process.exit(1)
}

const deployments = await readSubnetActor(args.address, network)

const { upgradeDiamond } = await lazyImport(
'./scripts/upgrade-sa-diamond',
)
const updatedFacets = await upgradeDiamond(deployments)
await saveDeploymentsFacets('subnet.actor.json', network, updatedFacets)
await saveSubnetActor(deployments, updatedFacets)
},
)
).addParam('address', 'The address to upgrade', undefined, types.string, false)

/** @type import('hardhat/config').HardhatUserConfig */
const config: HardhatUserConfig = {
Expand Down
4 changes: 2 additions & 2 deletions contracts/ops/upgrade-gw-diamond.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ then
exit 1
fi

NETWORK=$1
NETWORK="$1"

if [ "$NETWORK" = "auto" ]; then
echo "[*] Automatically getting chainID for network"
source ops/chain-id.sh
fi


npx hardhat upgrade-gw-diamond --network ${NETWORK}
npx hardhat upgrade-gw-diamond --network "${NETWORK}"
9 changes: 5 additions & 4 deletions contracts/ops/upgrade-sa-diamond.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,19 @@
set -eu
set -o pipefail

if [ $# -ne 1 ]
if [ $# -ne 2 ]
then
echo "Expected a single argument with the name of the network to deploy (localnet, calibrationnet, mainnet)"
echo "Expected an argument with the name of the network to deploy (localnet, calibrationnet, mainnet) followed by an argument for the Subnet actor address to upgrade"
exit 1
fi

NETWORK=$1
NETWORK="$1"
SUBNET_ACTOR_ADDRESS="$2"

if [ "$NETWORK" = "auto" ]; then
echo "[*] Automatically getting chainID for network"
source ops/chain-id.sh
fi


npx hardhat upgrade-sa-diamond --network ${NETWORK}
npx hardhat upgrade-sa-diamond --network "${NETWORK}" --address "$SUBNET_ACTOR_ADDRESS"
4 changes: 2 additions & 2 deletions contracts/ops/upgrade-sr-diamond.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ then
exit 1
fi

NETWORK=$1
NETWORK="$1"

if [ "$NETWORK" = "auto" ]; then
echo "[*] Automatically getting chainID for network"
source ops/chain-id.sh
fi


npx hardhat upgrade-sr-diamond --network ${NETWORK}
npx hardhat upgrade-sr-diamond --network "${NETWORK}"
78 changes: 78 additions & 0 deletions contracts/scripts/deploy-registry.template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ export async function deploy() {
const gatewayAddress = GATEWAY.Gateway
const txArgs = await getTransactionFees()

const subnetActorDeployFacets = []

// deploy
const getterFacet = await deployContractWithDeployer(
deployer,
Expand All @@ -42,6 +44,14 @@ export async function deploy() {
)
const getterSelectors = getSelectors(getterFacet)

subnetActorDeployFacets.push({
name: 'SubnetActorGetterFacet',
libs: {
SubnetIDHelper: LIBMAP['SubnetIDHelper'],
},
address: getterFacet.address,
})

const managerFacet = await deployContractWithDeployer(
deployer,
'SubnetActorManagerFacet',
Expand All @@ -50,6 +60,12 @@ export async function deploy() {
)
const managerSelectors = getSelectors(managerFacet)

subnetActorDeployFacets.push({
name: 'SubnetActorManagerFacet',
libs: {},
address: managerFacet.address,
})

const pauserFacet = await deployContractWithDeployer(
deployer,
'SubnetActorPauseFacet',
Expand All @@ -58,13 +74,24 @@ export async function deploy() {
)
const pauserSelectors = getSelectors(pauserFacet)

subnetActorDeployFacets.push({
name: 'SubnetActorPauseFacet',
libs: {},
address: pauserFacet.address,
})

const rewarderFacet = await deployContractWithDeployer(
deployer,
'SubnetActorRewardFacet',
{},
txArgs,
)
const rewarderSelectors = getSelectors(rewarderFacet)
subnetActorDeployFacets.push({
name: 'SubnetActorRewardFacet',
libs: {},
address: rewarderFacet.address,
})

const checkpointerFacet = await deployContractWithDeployer(
deployer,
Expand All @@ -73,6 +100,50 @@ export async function deploy() {
txArgs,
)
const checkpointerSelectors = getSelectors(checkpointerFacet)
subnetActorDeployFacets.push({
name: 'SubnetActorCheckpointingFacet',
libs: {},
address: checkpointerFacet.address,
})

const diamondCutFacet = await deployContractWithDeployer(
deployer,
'DiamondCutFacet',
{},
txArgs,
)
const diamondCutSelectors = getSelectors(diamondCutFacet)
subnetActorDeployFacets.push({
name: 'DiamondCutFacet',
libs: {},
address: diamondCutFacet.address,
})

const diamondLoupeFacet = await deployContractWithDeployer(
deployer,
'DiamondLoupeFacet',
{},
txArgs,
)
const diamondLoupeSelectors = getSelectors(diamondLoupeFacet)
subnetActorDeployFacets.push({
name: 'DiamondLoupeFacet',
libs: {},
address: diamondLoupeFacet.address,
})

const ownershipFacet = await deployContractWithDeployer(
deployer,
'OwnershipFacet',
{},
txArgs,
)
const ownershipSelectors = getSelectors(ownershipFacet)
subnetActorDeployFacets.push({
name: 'OwnershipFacet',
libs: {},
address: ownershipFacet.address,
})

//deploy subnet registry diamond
const registry = await ethers.getContractFactory('SubnetRegistryDiamond', {
Expand All @@ -86,11 +157,17 @@ export async function deploy() {
rewarderFacet: rewarderFacet.address,
checkpointerFacet: checkpointerFacet.address,
pauserFacet: pauserFacet.address,
diamondCutFacet: diamondCutFacet.address,
diamondLoupeFacet: diamondLoupeFacet.address,
ownershipFacet: ownershipFacet.address,
subnetActorGetterSelectors: getterSelectors,
subnetActorManagerSelectors: managerSelectors,
subnetActorRewarderSelectors: rewarderSelectors,
subnetActorCheckpointerSelectors: checkpointerSelectors,
subnetActorPauserSelectors: pauserSelectors,
subnetActorDiamondCutSelectors: diamondCutSelectors,
subnetActorDiamondLoupeSelectors: diamondLoupeSelectors,
subnetActorOwnershipSelectors: ownershipSelectors,
creationPrivileges: Number(mode),
}

Expand Down Expand Up @@ -143,5 +220,6 @@ export async function deploy() {
return {
SubnetRegistry: subnetRegistryAddress,
Facets: facets,
SubnetActorFacets: subnetActorDeployFacets,
}
}
7 changes: 4 additions & 3 deletions contracts/scripts/upgrade-sa-diamond.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ import {
* @returns An object of updated facets.
*/
async function upgradeSubnetActorDiamond(deployments) {
const gatewayDiamondAddress = deployments.SubnetActorDiamond
const subnetActorDiamondAddress = deployments.SubnetActorDiamond

const onChainFacets = await getFacets(subnetActorDiamondAddress)

const onChainFacets = await getFacets(gatewayDiamondAddress)
const updatedFacets = {}
const onChainFacetBytecodes = await getOnChainBytecodeFromFacets(
onChainFacets,
Expand All @@ -26,7 +27,7 @@ async function upgradeSubnetActorDiamond(deployments) {
await upgradeFacet(
facet,
onChainFacets,
gatewayDiamondAddress,
subnetActorDiamondAddress,
updatedFacets,
onChainFacetBytecodes,
deployments,
Expand Down
21 changes: 21 additions & 0 deletions contracts/src/SubnetRegistryDiamond.sol
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,17 @@ contract SubnetRegistryDiamond {
address rewarderFacet;
address checkpointerFacet;
address pauserFacet;
address diamondCutFacet;
address diamondLoupeFacet;
address ownershipFacet;
bytes4[] subnetActorGetterSelectors;
bytes4[] subnetActorManagerSelectors;
bytes4[] subnetActorRewarderSelectors;
bytes4[] subnetActorCheckpointerSelectors;
bytes4[] subnetActorPauserSelectors;
bytes4[] subnetActorDiamondCutSelectors;
bytes4[] subnetActorDiamondLoupeSelectors;
bytes4[] subnetActorOwnershipSelectors;
SubnetCreationPrivileges creationPrivileges;
}

Expand All @@ -49,6 +55,15 @@ contract SubnetRegistryDiamond {
if (params.pauserFacet == address(0)) {
revert FacetCannotBeZero();
}
if (params.diamondCutFacet == address(0)) {
revert FacetCannotBeZero();
}
if (params.diamondLoupeFacet == address(0)) {
revert FacetCannotBeZero();
}
if (params.ownershipFacet == address(0)) {
revert FacetCannotBeZero();
}

LibDiamond.setContractOwner(msg.sender);
LibDiamond.diamondCut({_diamondCut: _diamondCut, _init: address(0), _calldata: new bytes(0)});
Expand All @@ -65,12 +80,18 @@ contract SubnetRegistryDiamond {
s.SUBNET_ACTOR_REWARD_FACET = params.rewarderFacet;
s.SUBNET_ACTOR_CHECKPOINTING_FACET = params.checkpointerFacet;
s.SUBNET_ACTOR_PAUSE_FACET = params.pauserFacet;
s.SUBNET_ACTOR_DIAMOND_CUT_FACET = params.diamondCutFacet;
s.SUBNET_ACTOR_LOUPE_FACET = params.diamondLoupeFacet;
s.SUBNET_ACTOR_OWNERSHIP_FACET = params.ownershipFacet;

s.subnetActorGetterSelectors = params.subnetActorGetterSelectors;
s.subnetActorManagerSelectors = params.subnetActorManagerSelectors;
s.subnetActorRewarderSelectors = params.subnetActorRewarderSelectors;
s.subnetActorCheckpointerSelectors = params.subnetActorCheckpointerSelectors;
s.subnetActorPauserSelectors = params.subnetActorPauserSelectors;
s.subnetActorDiamondCutSelectors = params.subnetActorDiamondCutSelectors;
s.subnetActorDiamondLoupeSelectors = params.subnetActorDiamondLoupeSelectors;
s.subnetActorOwnershipSelectors = params.subnetActorOwnershipSelectors;

s.creationPrivileges = params.creationPrivileges;
}
Expand Down
Loading
Loading