Skip to content

Commit

Permalink
Subnet registry to deploy upgradeable subnet actors (#822)
Browse files Browse the repository at this point in the history
  • Loading branch information
snissn authored Mar 20, 2024
1 parent 017daa7 commit f2d8744
Show file tree
Hide file tree
Showing 17 changed files with 273 additions and 69 deletions.
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:
./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

0 comments on commit f2d8744

Please sign in to comment.