Skip to content
This repository has been archived by the owner on Jan 11, 2024. It is now read-only.

Commit

Permalink
Diamond registry (#153)
Browse files Browse the repository at this point in the history
* integrate diamond subnet registry

* make selectors storage

* revert openzeppelin changes

* more comments

* update registry template

* fix error

* fix error

* fix error

* fix errors

* fix errors

* fix errors

* fix tests

* fix tests

* update template

* reduce registry size

* remove unused methods

* clean up code

* update registry

* add clone factory

* more logs

* update deployment script

* remove compile

* format

* update template

* remove clone factory

* remove clone factory

* fix test

* revert deleted functions

* update deployment

* remove extra logs

* fix test setup

* fixing unit tests

* fixing unit tests

* fix latest subnet bug

* update nonce when subnet created

* update comment
  • Loading branch information
cryptoAtwill authored Jul 26, 2023
1 parent 6f6a26a commit 1ded739
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 26 deletions.
48 changes: 41 additions & 7 deletions scripts/deploy-registry.template
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import hre, { ethers } from 'hardhat';
import { getTransactionFees } from './util';
import { ethers } from 'hardhat';
import { deployContractWithDeployer, getTransactionFees } from './util';

const { getSelectors } = require('./js/diamond.js')

async function main() {
try {

await hre.run('compile');

const [deployer] = await ethers.getSigners();
const balance = await deployer.getBalance();

Expand All @@ -15,8 +14,43 @@ async function main() {
const txArgs = await getTransactionFees();

// deploy
const registry = await ethers.getContractFactory('SubnetRegistry', { signer: deployer, libraries: LIBMAP });
const contract = await registry.deploy(gatewayAddress, txArgs);
const getterFacet = await deployContractWithDeployer(
deployer,
"SubnetActorGetterFacet",
{},
txArgs
);
const getterSelectors = getSelectors(getterFacet);
console.log("getter address:", getterFacet.address);

const managerFacet = await deployContractWithDeployer(
deployer,
"SubnetActorManagerFacet",
{
AccountHelper: LIBMAP['AccountHelper'],
CheckpointHelper: LIBMAP['CheckpointHelper'],
EpochVoteSubmissionHelper: LIBMAP['EpochVoteSubmissionHelper'],
ExecutableQueueHelper: LIBMAP['ExecutableQueueHelper'],
SubnetIDHelper: LIBMAP['SubnetIDHelper'],
CrossMsgHelper: LIBMAP['CrossMsgHelper'],
},
txArgs
);
const managerSelectors = getSelectors(managerFacet);
console.log("manager address:", managerFacet.address);

const registry = await ethers.getContractFactory('SubnetRegistry', { signer: deployer, libraries: {
"SubnetIDHelper": LIBMAP["SubnetIDHelper"]
}});

const contract = await registry.deploy(
gatewayAddress,
getterFacet.address,
managerFacet.address,
getterSelectors,
managerSelectors,
txArgs
);

// FEVM:
console.log(`registry contract deployed to: ${contract.address}`);
Expand Down
75 changes: 58 additions & 17 deletions src/SubnetRegistry.sol
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.19;

import {SubnetActor} from "./SubnetActor.sol";
import {SubnetID} from "./structs/Subnet.sol";
import {SubnetIDHelper} from "./lib/SubnetIDHelper.sol";
import {SubnetActorDiamond} from "./SubnetActorDiamond.sol";
import {IDiamond} from "./interfaces/IDiamond.sol";

contract SubnetRegistry {
using SubnetIDHelper for SubnetID;
address public immutable gateway;

/// The getter and manager facet shared by diamond
address public getterFacet;
address public managerFacet;

/// The subnet getter facet functions selectors
bytes4[] public subnetGetterSelectors;
/// The subnet manager facet functions selectors
bytes4[] public subnetManagerSelectors;

/// @notice Mapping that tracks the deployed subnet actors per user.
/// Key is the hash of Subnet ID, values are addresses.
Expand All @@ -18,28 +26,55 @@ contract SubnetRegistry {
/// owner => nonce
mapping(address => uint64) public userNonces;

address public immutable gateway;

/// @notice Event emitted when a new subnet is deployed.
event SubnetDeployed(address subnetAddr);

error WrongGateway();
error ZeroGatewayAddress();
error CannotFindSubnet();
error UnknownSubnet();

constructor(address _gateway) {
if (_gateway == address(0)) {
revert ZeroGatewayAddress();
}
constructor(
address _gateway,
address _getterFacet,
address _managerFacet,
bytes4[] memory _subnetGetterSelectors,
bytes4[] memory _subnetManagerSelectors
) {
gateway = _gateway;

getterFacet = _getterFacet;
managerFacet = _managerFacet;

subnetGetterSelectors = _subnetGetterSelectors;
subnetManagerSelectors = _subnetManagerSelectors;
}

function newSubnetActor(SubnetActor.ConstructParams calldata params) external returns (address subnetAddr) {
if (params.ipcGatewayAddr != gateway) {
/// @notice Deploys a new subnet actor.
/// @param _params The constructor params for Subnet Actor Diamond.
function newSubnetActor(
SubnetActorDiamond.ConstructorParams calldata _params
) external returns (address subnetAddr) {
if (_params.ipcGatewayAddr != gateway) {
revert WrongGateway();
}

subnetAddr = address(new SubnetActor(params));
IDiamond.FacetCut[] memory diamondCut = new IDiamond.FacetCut[](2);

// set the diamond cut for subnet getter
diamondCut[0] = IDiamond.FacetCut({
facetAddress: getterFacet,
action: IDiamond.FacetCutAction.Add,
functionSelectors: subnetGetterSelectors
});

// set the diamond cut for subnet manager
diamondCut[1] = IDiamond.FacetCut({
facetAddress: managerFacet,
action: IDiamond.FacetCutAction.Add,
functionSelectors: subnetManagerSelectors
});

subnetAddr = address(new SubnetActorDiamond(diamondCut, _params));

subnets[msg.sender][userNonces[msg.sender]] = subnetAddr;
++userNonces[msg.sender];
Expand All @@ -50,9 +85,15 @@ contract SubnetRegistry {
/// @notice Returns the address of the latest subnet actor
/// deployed by a user
function latestSubnetDeployed(address owner) external view returns (address subnet) {
subnet = subnets[owner][userNonces[owner] - 1];
uint64 nonce = userNonces[owner];
// need unchecked when nonce == 0 or else will underflow
unchecked {
nonce -= 1;
}

subnet = subnets[owner][nonce];
if (subnet == address(0)) {
revert ZeroGatewayAddress();
revert CannotFindSubnet();
}
}

Expand All @@ -61,7 +102,7 @@ contract SubnetRegistry {
function getSubnetDeployedByNonce(address owner, uint64 nonce) external view returns (address subnet) {
subnet = subnets[owner][nonce];
if (subnet == address(0)) {
revert ZeroGatewayAddress();
revert CannotFindSubnet();
}
}
}
18 changes: 16 additions & 2 deletions test/SubnetRegistry.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ import "forge-std/console.sol";

import "../src/SubnetRegistry.sol";

import "../src/subnet/SubnetActorGetterFacet.sol";
import "../src/subnet/SubnetActorManagerFacet.sol";

import "../src/lib/SubnetIDHelper.sol";

contract SubnetRegistryTest is Test {
using SubnetIDHelper for SubnetID;

Expand All @@ -26,7 +31,16 @@ contract SubnetRegistryTest is Test {
SubnetRegistry sr;

function setUp() public {
sr = new SubnetRegistry(DEFAULT_IPC_GATEWAY_ADDR);
bytes4[] memory mockedSelectors = new bytes4[](1);
mockedSelectors[0] = 0x6cb2ecee;

bytes4[] memory mockedSelectors2 = new bytes4[](1);
mockedSelectors2[0] = 0x133f74ea;

address getter = address(new SubnetActorGetterFacet());
address manager = address(new SubnetActorManagerFacet());

sr = new SubnetRegistry(DEFAULT_IPC_GATEWAY_ADDR, getter, manager, mockedSelectors, mockedSelectors2);
}

function test_Registry_Deployment_Works() public {
Expand All @@ -53,7 +67,7 @@ contract SubnetRegistryTest is Test {
uint8 _majorityPercentage
) public {
vm.startPrank(DEFAULT_SENDER);
SubnetActor.ConstructParams memory params = SubnetActor.ConstructParams({
SubnetActorDiamond.ConstructorParams memory params = SubnetActorDiamond.ConstructorParams({
parentId: SubnetID({root: ROOTNET_CHAINID, route: new address[](0)}),
name: _name,
ipcGatewayAddr: _ipcGatewayAddr,
Expand Down

0 comments on commit 1ded739

Please sign in to comment.