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

perf: Improvement/zksync-support #3

Merged
merged 1 commit into from
Oct 31, 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
6 changes: 5 additions & 1 deletion solidity/contracts/isms/multisig/StorageMultisigIsm.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {AbstractMessageIdMultisigIsm} from "./AbstractMessageIdMultisigIsm.sol";
import {IInterchainSecurityModule} from "../../interfaces/IInterchainSecurityModule.sol";
import {IThresholdAddressFactory} from "../../interfaces/IThresholdAddressFactory.sol";
import {MinimalProxy} from "../../libs/MinimalProxy.sol";
import {PackageVersioned} from "../../PackageVersioned.sol";

// ============ External Imports ============
import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
Expand Down Expand Up @@ -81,7 +82,10 @@ contract StorageMessageIdMultisigIsm is
) AbstractStorageMultisigIsm(_validators, _threshold) {}
}

abstract contract StorageMultisigIsmFactory is IThresholdAddressFactory {
abstract contract StorageMultisigIsmFactory is
IThresholdAddressFactory,
PackageVersioned
{
/**
* @notice Emitted when a multisig module is deployed
* @param module The deployed ISM
Expand Down
24 changes: 12 additions & 12 deletions solidity/core-utils/zksync/artifacts/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ const currentDirectory = path.dirname(currentFilePath);
* @param directory The directory to read artifact files from.
* @return An array of artifact file names that end with '.js'.
*/
const getArtifactFiles = (directory: string): string[] => {
function getArtifactFiles(directory: string): string[] {
return readdirSync(directory).filter((file) => file.endsWith('.js')); // Filter for .js files
};
}

/**
* @dev Exports the list of artifact names without the .js extension.
Expand All @@ -47,18 +47,18 @@ export const zksyncArtifactNames = getArtifactFiles(
* @param name The name of the artifact to check.
* @return True if the artifact exists, false otherwise.
*/
export const artifactExists = (name: string): boolean => {
export function artifactExists(name: string): boolean {
return zksyncArtifactNames.includes(`${name}.js`); // Check if the artifact file exists
};
}

/**
* @dev Loads a ZkSync artifact by its name.
* @param name The name of the artifact to load.
* @return The loaded ZkSyncArtifact or undefined if it cannot be loaded.
*/
const loadZkArtifact = async (
export async function loadZkArtifact(
name: string,
): Promise<ZkSyncArtifact | undefined> => {
): Promise<ZkSyncArtifact | undefined> {
try {
const artifactModule = await import(
join(currentDirectory, 'output', `${name}.js`)
Expand All @@ -68,13 +68,13 @@ const loadZkArtifact = async (
console.error(`Error loading artifact: ${name}`, error);
return undefined;
}
};
}

/**
* @dev Loads all ZkSync artifacts into a map.
* @return A map of artifact names to their corresponding ZkSync artifacts.
*/
export const loadAllZkArtifacts = async (): Promise<ArtifactMap> => {
export async function loadAllZkArtifacts(): Promise<ArtifactMap> {
const zkSyncArtifactMap: ArtifactMap = {};

// Load all artifacts concurrently
Expand All @@ -88,15 +88,15 @@ export const loadAllZkArtifacts = async (): Promise<ArtifactMap> => {
await Promise.all(loadPromises);

return zkSyncArtifactMap; // Return the populated artifact map
};
}

/**
* @dev Retrieves a specific ZkSync artifact by its file name.
* @param name The name of the artifact to retrieve.
* @return The loaded ZkSyncArtifact or undefined if it cannot be loaded.
*/
export const getZkArtifactByName = async (
export async function getZkArtifactByName(
name: string,
): Promise<ZkSyncArtifact | undefined> => {
): Promise<ZkSyncArtifact | undefined> {
return loadZkArtifact(name);
};
}
8 changes: 6 additions & 2 deletions solidity/test/isms/MultisigIsm.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,9 @@ contract MerkleRootMultisigIsmTest is AbstractMultisigIsmTest {
mailbox = new TestMailbox(ORIGIN);
merkleTreeHook = new TestMerkleTreeHook(address(mailbox));
noopHook = new TestPostDispatchHook();
factory = new StaticMerkleRootMultisigIsmFactory();
factory = IThresholdAddressFactory(
address(new StaticMerkleRootMultisigIsmFactory())
);
mailbox.setDefaultHook(address(merkleTreeHook));
mailbox.setRequiredHook(address(noopHook));
}
Expand Down Expand Up @@ -285,7 +287,9 @@ contract MessageIdMultisigIsmTest is AbstractMultisigIsmTest {
merkleTreeHook = new TestMerkleTreeHook(address(mailbox));
noopHook = new TestPostDispatchHook();

factory = new StaticMessageIdMultisigIsmFactory();
factory = IThresholdAddressFactory(
address(new StaticMessageIdMultisigIsmFactory())
);
mailbox.setDefaultHook(address(merkleTreeHook));
mailbox.setRequiredHook(address(noopHook));
}
Expand Down
4 changes: 2 additions & 2 deletions typescript/cli/src/deploy/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ import { runSingleChainSelectionStep } from '../utils/chains.js';
import { indentYamlOrJson } from '../utils/files.js';

import {
checkTechStackCoreConfigCompatibility,
completeDeploy,
isIsmCompatible,
prepareDeploy,
runDeployPlanStep,
runPreflightChecksForChains,
Expand Down Expand Up @@ -85,7 +85,7 @@ export async function runCoreDeploy(params: DeployParams) {
const { technicalStack: chainTechnicalStack } =
context.multiProvider.getChainMetadata(chain);

if (!checkTechStackCoreConfigCompatibility({ chainTechnicalStack, config })) {
if (!isIsmCompatible({ chainTechnicalStack, config })) {
logRed(
'ERROR: CoreConfig is not compatible with the selected Chain Technical Stack!',
);
Expand Down
14 changes: 5 additions & 9 deletions typescript/cli/src/deploy/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import {
logGray,
logGreen,
logPink,
logRed,
logTable,
} from '../logger.js';
import { nativeBalancesAreSufficient } from '../utils/balances.js';
Expand Down Expand Up @@ -199,21 +198,18 @@ function transformChainMetadataForDisplay(chainMetadata: ChainMetadata) {
* @param {CoreConfig} params.config - The core configuration to check.
* @returns {boolean} True if the configuration is compatible, false otherwise.
*/
export function checkTechStackCoreConfigCompatibility({
export function isIsmCompatible({
chainTechnicalStack,
config,
}: {
chainTechnicalStack: ChainTechnicalStack | undefined;
config: CoreConfig;
}): boolean {
if (shouldSkipStaticDeployment(chainTechnicalStack)) return true;

// Static deployment is not available on certain chains (e.g., ZKSync) for aggregation ISMs.
if (
shouldSkipStaticDeployment(chainTechnicalStack) &&
return (
typeof config.defaultIsm !== 'string' &&
config.defaultIsm.type === IsmType.AGGREGATION
) {
logRed('⛔ Static contract deployment not available on ZKSync!');
return false;
}
return true;
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ nativeToken:
decimals: 18
name: Ether
symbol: ETH
protocol: zksync
protocol: ethereum
rpcUrls:
- http: http://127.0.0.1:8011
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ nativeToken:
decimals: 18
name: Ether
symbol: ETH
protocol: zksync
protocol: ethereum
rpcUrls:
- http: http://127.0.0.1:3050
4 changes: 1 addition & 3 deletions typescript/sdk/src/core/EvmCoreModule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -468,9 +468,7 @@ export class EvmCoreModule extends HyperlaneModule<
// Check if we should skip static address set deployment
if (shouldSkipStaticDeployment(technicalStack)) {
return createDefaultProxyFactoryFactories();
} else {
// Otherwise, deploy ISM factories
return await EvmCoreModule.deployIsmFactories(params);
}
return EvmCoreModule.deployIsmFactories(params);
}
}
5 changes: 3 additions & 2 deletions typescript/sdk/src/deploy/HyperlaneDeployer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -463,8 +463,9 @@ export abstract class HyperlaneDeployer<
let verificationInput: ContractVerificationInput;
if (isZKSyncChain) {
if (!artifact) {
// TODO: ARTIFACT NOT FOUND ERROR
throw Error('Artifact not found');
throw new Error(
`No ZKSync artifact found for contract: ${contractName}`,
);
}
verificationInput = await getContractVerificationInputForZKSync({
name: contractName,
Expand Down
4 changes: 2 additions & 2 deletions typescript/sdk/src/deploy/proxy.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { ethers } from 'ethers';
import * as zk from 'zksync-ethers';
import { Provider as ZKSyncProvider } from 'zksync-ethers';

import { Address, eqAddress } from '@hyperlane-xyz/utils';

type Provider = ethers.providers.Provider | zk.Provider;
type Provider = ethers.providers.Provider | ZKSyncProvider;

export type UpgradeConfig = {
timelock: {
Expand Down
6 changes: 2 additions & 4 deletions typescript/sdk/src/deploy/verify/ZKSyncContractVerifier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ export class ZKSyncContractVerifier {
* @notice Creates a mapping of contract names to source names from build artifacts
* @dev This method processes the input to create a mapping required for constructing fully qualified contract names
*/
private async createContractSourceMapFromBuildArtifacts() {
private createContractSourceMapFromBuildArtifacts() {
const contractRegex = /contract\s+([A-Z][a-zA-Z0-9]*)/g;
Object.entries((buildArtifact as BuildArtifact).input.sources).forEach(
([sourceName, { content }]) => {
Expand Down Expand Up @@ -179,9 +179,7 @@ export class ZKSyncContractVerifier {
'Sending request to explorer...',
);

let response: Response;

response = await fetch(url.toString(), {
const response = await fetch(url.toString(), {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(options),
Expand Down
6 changes: 3 additions & 3 deletions typescript/sdk/src/deploy/verify/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import { ChainMap, ChainName } from '../../types.js';

import { ContractVerificationInput } from './types.js';

const { Interface } = await import('@ethersproject/abi');

export function formatFunctionArguments(
fragment: utils.Fragment,
args: any[],
Expand Down Expand Up @@ -90,9 +92,7 @@ export async function getContractVerificationInputForZKSync({
);
}

export async function encodeArguments(abi: any, constructorArgs: any[]) {
const { Interface } = await import('@ethersproject/abi');

export function encodeArguments(abi: any, constructorArgs: any[]): string {
const contractInterface = new Interface(abi);
let deployArgumentsEncoded;
try {
Expand Down
38 changes: 8 additions & 30 deletions typescript/sdk/src/ism/EvmIsmModule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -420,7 +420,6 @@ export class EvmIsmModule extends HyperlaneModule<
factory: new TrustedRelayerIsm__factory(),
contractName: IsmType.TRUSTED_RELAYER,
constructorArgs: [this.args.addresses.mailbox, config.relayer],
implementationAddress: undefined,
});

case IsmType.TEST_ISM:
Expand All @@ -431,56 +430,35 @@ export class EvmIsmModule extends HyperlaneModule<
constructorArgs: [],
});
case IsmType.STORAGE_MESSAGE_ID_MULTISIG:
return this.deployStorageMessageIdMultisigIsm({
config,
logger,
});
case IsmType.STORAGE_MERKLE_ROOT_MULTISIG:
return this.deployStorageMultisigIsm({
config,
logger,
});

default:
throw new Error(`Unsupported ISM type ${ismType}`);
}
}

// TODO: handle logging part
protected async deployStorageMessageIdMultisigIsm({
config,
logger,
}: {
config: MultisigIsmConfig;
logger: Logger;
}): Promise<IMultisigIsm> {
const signer = this.multiProvider.getSigner(this.chain);

const contract = await this.deployer.deployContractFromFactory({
chain: this.chain,
factory: new StorageMessageIdMultisigIsm__factory(),
contractName: IsmType.STORAGE_MESSAGE_ID_MULTISIG,
constructorArgs: [config.validators, config.threshold],
});
return IMultisigIsm__factory.connect(contract.address, signer);
}

// TODO: handle logging part
protected async deployStorageMultisigIsm({
config,
logger,
}: {
config: MultisigIsmConfig;
logger: Logger;
}): Promise<IMultisigIsm> {
const signer = this.multiProvider.getSigner(this.chain);

const factory =
config.type === IsmType.STORAGE_MERKLE_ROOT_MULTISIG
? new StorageMerkleRootMultisigIsm__factory()
: new StorageMessageIdMultisigIsm__factory();

const contract = await this.deployer.deployContractFromFactory({
chain: this.chain,
factory: new StorageMerkleRootMultisigIsm__factory(),
contractName: IsmType.STORAGE_MERKLE_ROOT_MULTISIG,
factory: factory,
contractName: config.type,
constructorArgs: [config.validators, config.threshold],
});

return IMultisigIsm__factory.connect(contract.address, signer);
}

Expand Down
Loading
Loading