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 2 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
14 changes: 12 additions & 2 deletions contracts/hardhat.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -291,14 +291,24 @@ 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 subnetRegistry = await getSubnetRegistry(network)
console.log(subnetRegistry)
const deployments = { SubnetActorDiamond: args.address , Facets: subnetRegistry.SubnetActorFacets }
console.log(deployments);

const { upgradeDiamond } = await lazyImport(
'./scripts/upgrade-sa-diamond',
)
const updatedFacets = await upgradeDiamond(deployments)
await saveDeploymentsFacets('subnet.actor.json', network, 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}"
70 changes: 70 additions & 0 deletions contracts/scripts/deploy-registry.template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ export async function deploy() {
const gatewayAddress = GATEWAY.Gateway
const txArgs = await getTransactionFees()

const subnetActorDeployFacets = []

// deploy
const getterFacet = await deployContractWithDeployer(
deployer,
Expand All @@ -27,6 +29,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 @@ -35,6 +45,15 @@ export async function deploy() {
)
const managerSelectors = getSelectors(managerFacet)

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




const pauserFacet = await deployContractWithDeployer(
deployer,
'SubnetActorPauseFacet',
Expand All @@ -43,13 +62,26 @@ 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 @@ -58,6 +90,39 @@ 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
});

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

const facetCuts = [] //TODO
Expand Down Expand Up @@ -127,5 +196,6 @@ export async function deploy() {
return {
SubnetRegistry: subnetRegistryAddress,
Facets: facets,
SubnetActorFacets: subnetActorDeployFacets,
}
}
11 changes: 8 additions & 3 deletions contracts/scripts/upgrade-sa-diamond.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,24 @@ import {
* @returns An object of updated facets.
*/
async function upgradeSubnetActorDiamond(deployments) {
const gatewayDiamondAddress = deployments.SubnetActorDiamond
const subnetActorDiamondAddress = deployments.SubnetActorDiamond
console.log("subnetActorDiamondAddress", subnetActorDiamondAddress)

const onChainFacets = await getFacets(gatewayDiamondAddress)
const onChainFacets = await getFacets(subnetActorDiamondAddress)
console.log('onChainFacets',onChainFacets)

const updatedFacets = {}
const onChainFacetBytecodes = await getOnChainBytecodeFromFacets(
onChainFacets,
)
console.log("onChainFacetBytecodes", onChainFacetBytecodes)

for (const facet of deployments.Facets) {
console.log("Facet", facet);
await upgradeFacet(
facet,
onChainFacets,
gatewayDiamondAddress,
subnetActorDiamondAddress,
updatedFacets,
onChainFacetBytecodes,
deployments,
Expand Down
1 change: 1 addition & 0 deletions contracts/scripts/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ export async function getFacets(diamondAddress: string): Promise<FacetMap> {
]

const provider = ethers.provider
console.log("diamondAddress",diamondAddress)
const diamond = new Contract(diamondAddress, diamondLoupeABI, provider)
const facetsData = await diamond.facets()

Expand Down
14 changes: 14 additions & 0 deletions contracts/src/SubnetRegistryDiamond.sol
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,15 @@ contract SubnetRegistryDiamond {
address rewarderFacet;
address checkpointerFacet;
address pauserFacet;
address diamondCutFacet;
address diamondLoupeFacet;
bytes4[] subnetActorGetterSelectors;
bytes4[] subnetActorManagerSelectors;
bytes4[] subnetActorRewarderSelectors;
bytes4[] subnetActorCheckpointerSelectors;
bytes4[] subnetActorPauserSelectors;
bytes4[] subnetActorDiamondCutSelectors;
bytes4[] subnetActorDiamondLoupeSelectors;
}

constructor(IDiamond.FacetCut[] memory _diamondCut, ConstructorParams memory params) {
Expand All @@ -47,6 +51,12 @@ contract SubnetRegistryDiamond {
if (params.pauserFacet == address(0)) {
revert FacetCannotBeZero();
}
if (params.diamondCutFacet == address(0)) {
revert FacetCannotBeZero();
}
if (params.diamondLoupeFacet == address(0)) {
revert FacetCannotBeZero();
}

LibDiamond.setContractOwner(msg.sender);
LibDiamond.diamondCut({_diamondCut: _diamondCut, _init: address(0), _calldata: new bytes(0)});
Expand All @@ -63,12 +73,16 @@ 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.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;
}

function _fallback() internal {
Expand Down
8 changes: 8 additions & 0 deletions contracts/src/lib/LibSubnetRegistryStorage.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ struct SubnetRegistryActorStorage {
address SUBNET_ACTOR_CHECKPOINTING_FACET;
// solhint-disable-next-line var-name-mixedcase
address SUBNET_ACTOR_PAUSE_FACET;
// solhint-disable-next-line var-name-mixedcase
address SUBNET_ACTOR_DIAMOND_CUT_FACET;
// solhint-disable-next-line var-name-mixedcase
address SUBNET_ACTOR_LOUPE_FACET;
/// The subnet actor getter facet functions selectors
bytes4[] subnetActorGetterSelectors;
/// The subnet actor manager facet functions selectors
Expand All @@ -25,6 +29,10 @@ struct SubnetRegistryActorStorage {
bytes4[] subnetActorCheckpointerSelectors;
/// The subnet actor pause facet functions selectors
bytes4[] subnetActorPauserSelectors;
/// The subnet actor diamond cut facet functions selectors
bytes4[] subnetActorDiamondCutSelectors;
/// The subnet actor loupe facet functions selectors
bytes4[] subnetActorDiamondLoupeSelectors;
/// @notice Mapping that tracks the deployed subnet actors per user.
/// Key is the hash of Subnet ID, values are addresses.
/// mapping owner => nonce => subnet
Expand Down
14 changes: 13 additions & 1 deletion contracts/src/subnetregistry/RegisterSubnetFacet.sol
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ contract RegisterSubnetFacet is ReentrancyGuard {
revert WrongGateway();
}

IDiamond.FacetCut[] memory diamondCut = new IDiamond.FacetCut[](5);
IDiamond.FacetCut[] memory diamondCut = new IDiamond.FacetCut[](7);

// set the diamond cut for subnet getter
diamondCut[0] = IDiamond.FacetCut({
Expand Down Expand Up @@ -57,6 +57,18 @@ contract RegisterSubnetFacet is ReentrancyGuard {
functionSelectors: s.subnetActorPauserSelectors
});

diamondCut[5] = IDiamond.FacetCut({
facetAddress: s.SUBNET_ACTOR_DIAMOND_CUT_FACET,
raulk marked this conversation as resolved.
Show resolved Hide resolved
action: IDiamond.FacetCutAction.Add,
functionSelectors: s.subnetActorDiamondCutSelectors
});

diamondCut[6] = IDiamond.FacetCut({
facetAddress: s.SUBNET_ACTOR_LOUPE_FACET,
action: IDiamond.FacetCutAction.Add,
functionSelectors: s.subnetActorDiamondLoupeSelectors
});

// slither-disable-next-line reentrancy-benign
subnetAddr = address(new SubnetActorDiamond(diamondCut, _params, msg.sender));

Expand Down
Loading