feat(utils): Set errorMessage argument for assert to required (#4121)

### Description

<!--
What's included in this PR?
-->

- Set errorMessage argument for assert to required

### Drive-by changes

<!--
Are there any minor or drive-by changes also included?
-->

### Related issues

<!--
- Fixes #[issue number here]
-->

### Backward compatibility

<!--
Are these changes backward compatible? Are there any infrastructure
implications, e.g. changes that would prohibit deploying older commits
using this infra tooling?

Yes/No
-->

### Testing

<!--
What kind of testing have these changes undergone?

None/Manual/Unit Tests
-->
pb/stride-va
Mohammed Hussan 4 months ago committed by GitHub
parent 5aa24611b3
commit dfa9087960
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 5
      .changeset/lazy-steaks-prove.md
  2. 5
      .changeset/light-bulldogs-confess.md
  3. 7
      typescript/sdk/src/core/HyperlaneCoreChecker.ts
  4. 36
      typescript/sdk/src/hook/EvmHookReader.ts
  5. 34
      typescript/sdk/src/ism/EvmIsmReader.ts
  6. 5
      typescript/sdk/src/ism/metadata/multisig.ts
  7. 2
      typescript/sdk/src/token/deploy.ts
  8. 4
      typescript/utils/src/validation.ts

@ -0,0 +1,5 @@
---
'@hyperlane-xyz/sdk': patch
---
add error message for all calls to assert util

@ -0,0 +1,5 @@
---
'@hyperlane-xyz/utils': minor
---
set the errorMessage argument as required for assert util function

@ -58,7 +58,12 @@ export class HyperlaneCoreChecker extends HyperlaneAppChecker<
const contracts = this.app.getContracts(chain);
const mailbox = contracts.mailbox;
const localDomain = await mailbox.localDomain();
assert(localDomain === this.multiProvider.getDomainId(chain));
assert(
localDomain === this.multiProvider.getDomainId(chain),
`local domain ${localDomain} does not match expected domain ${this.multiProvider.getDomainId(
chain,
)} for ${chain}`,
);
const actualIsm = await mailbox.defaultIsm();

@ -69,6 +69,10 @@ export interface HookReader {
derivePausableConfig(
address: Address,
): Promise<WithAddress<PausableHookConfig>>;
assertHookType(
hookType: OnchainHookType,
expectedType: OnchainHookType,
): void;
}
export class EvmHookReader implements HookReader {
@ -152,7 +156,7 @@ export class EvmHookReader implements HookReader {
address: Address,
): Promise<WithAddress<MerkleTreeHookConfig>> {
const hook = MerkleTreeHook__factory.connect(address, this.provider);
assert((await hook.hookType()) === OnchainHookType.MERKLE_TREE);
this.assertHookType(await hook.hookType(), OnchainHookType.MERKLE_TREE);
return {
address,
@ -164,7 +168,7 @@ export class EvmHookReader implements HookReader {
address: Address,
): Promise<WithAddress<AggregationHookConfig>> {
const hook = StaticAggregationHook__factory.connect(address, this.provider);
assert((await hook.hookType()) === OnchainHookType.AGGREGATION);
this.assertHookType(await hook.hookType(), OnchainHookType.AGGREGATION);
const hooks = await hook.hooks(ethers.constants.AddressZero);
const hookConfigs: DerivedHookConfig[] = await concurrentMap(
@ -185,8 +189,9 @@ export class EvmHookReader implements HookReader {
address,
this.provider,
);
assert(
(await hook.hookType()) === OnchainHookType.INTERCHAIN_GAS_PAYMASTER,
this.assertHookType(
await hook.hookType(),
OnchainHookType.INTERCHAIN_GAS_PAYMASTER,
);
const owner = await hook.owner();
@ -259,7 +264,7 @@ export class EvmHookReader implements HookReader {
address: Address,
): Promise<WithAddress<ProtocolFeeHookConfig>> {
const hook = ProtocolFee__factory.connect(address, this.provider);
assert((await hook.hookType()) === OnchainHookType.PROTOCOL_FEE);
this.assertHookType(await hook.hookType(), OnchainHookType.PROTOCOL_FEE);
const owner = await hook.owner();
const maxProtocolFee = await hook.MAX_PROTOCOL_FEE();
@ -281,7 +286,7 @@ export class EvmHookReader implements HookReader {
): Promise<WithAddress<OpStackHookConfig>> {
const hook = OPStackHook__factory.connect(address, this.provider);
const owner = await hook.owner();
assert((await hook.hookType()) === OnchainHookType.ID_AUTH_ISM);
this.assertHookType(await hook.hookType(), OnchainHookType.ID_AUTH_ISM);
const messengerContract = await hook.l1Messenger();
const destinationDomain = await hook.destinationDomain();
@ -301,7 +306,7 @@ export class EvmHookReader implements HookReader {
address: Address,
): Promise<WithAddress<DomainRoutingHookConfig>> {
const hook = DomainRoutingHook__factory.connect(address, this.provider);
assert((await hook.hookType()) === OnchainHookType.ROUTING);
this.assertHookType(await hook.hookType(), OnchainHookType.ROUTING);
const owner = await hook.owner();
const domainHooks = await this.fetchDomainHooks(hook);
@ -321,7 +326,10 @@ export class EvmHookReader implements HookReader {
address,
this.provider,
);
assert((await hook.hookType()) === OnchainHookType.FALLBACK_ROUTING);
this.assertHookType(
await hook.hookType(),
OnchainHookType.FALLBACK_ROUTING,
);
const owner = await hook.owner();
const domainHooks = await this.fetchDomainHooks(hook);
@ -367,7 +375,7 @@ export class EvmHookReader implements HookReader {
address: Address,
): Promise<WithAddress<PausableHookConfig>> {
const hook = PausableHook__factory.connect(address, this.provider);
assert((await hook.hookType()) === OnchainHookType.PAUSABLE);
this.assertHookType(await hook.hookType(), OnchainHookType.PAUSABLE);
const owner = await hook.owner();
const paused = await hook.paused();
@ -390,4 +398,14 @@ export class EvmHookReader implements HookReader {
this.provider.setLogLevel(level);
}
}
assertHookType(
hookType: OnchainHookType,
expectedType: OnchainHookType,
): void {
assert(
hookType === expectedType,
`expected hook type to be ${expectedType}, got ${hookType}`,
);
}
}

@ -7,7 +7,6 @@ import {
OPStackIsm__factory,
PausableIsm__factory,
StaticAggregationIsm__factory,
TestIsm__factory,
TrustedRelayerIsm__factory,
} from '@hyperlane-xyz/core';
import {
@ -44,6 +43,10 @@ export interface IsmReader {
address: Address,
): Promise<WithAddress<MultisigIsmConfig>>;
deriveNullConfig(address: Address): Promise<WithAddress<NullIsmConfig>>;
assertModuleType(
moduleType: ModuleType,
expectedModuleType: ModuleType,
): void;
}
export class EvmIsmReader implements IsmReader {
@ -98,7 +101,7 @@ export class EvmIsmReader implements IsmReader {
this.provider,
);
const owner = await ism.owner();
assert((await ism.moduleType()) === ModuleType.ROUTING);
this.assertModuleType(await ism.moduleType(), ModuleType.ROUTING);
const domains: RoutingIsmConfig['domains'] = {};
const domainIds = await ism.domains();
@ -139,7 +142,7 @@ export class EvmIsmReader implements IsmReader {
address: Address,
): Promise<WithAddress<AggregationIsmConfig>> {
const ism = StaticAggregationIsm__factory.connect(address, this.provider);
assert((await ism.moduleType()) === ModuleType.AGGREGATION);
this.assertModuleType(await ism.moduleType(), ModuleType.AGGREGATION);
const [modules, threshold] = await ism.modulesAndThreshold(
ethers.constants.AddressZero,
@ -167,6 +170,7 @@ export class EvmIsmReader implements IsmReader {
assert(
moduleType === ModuleType.MERKLE_ROOT_MULTISIG ||
moduleType === ModuleType.MESSAGE_ID_MULTISIG,
`expected module type to be ${ModuleType.MERKLE_ROOT_MULTISIG} or ${ModuleType.MESSAGE_ID_MULTISIG}, got ${moduleType}`,
);
const ismType =
@ -189,14 +193,20 @@ export class EvmIsmReader implements IsmReader {
async deriveNullConfig(
address: Address,
): Promise<WithAddress<NullIsmConfig>> {
// if it has trustedRelayer() property --> TrustedRelayer ISM
const ism = IInterchainSecurityModule__factory.connect(
address,
this.provider,
);
this.assertModuleType(await ism.moduleType(), ModuleType.NULL);
// if it has trustedRelayer() property --> TRUSTED_RELAYER
const trustedRelayerIsm = TrustedRelayerIsm__factory.connect(
address,
this.provider,
);
try {
const relayer = await trustedRelayerIsm.trustedRelayer();
assert((await trustedRelayerIsm.moduleType()) === ModuleType.NULL);
return {
address,
relayer,
@ -214,7 +224,6 @@ export class EvmIsmReader implements IsmReader {
try {
const paused = await pausableIsm.paused();
const owner = await pausableIsm.owner();
assert((await pausableIsm.moduleType()) === ModuleType.NULL);
return {
address,
owner,
@ -231,7 +240,6 @@ export class EvmIsmReader implements IsmReader {
// if it has VERIFIED_MASK_INDEX, it's AbstractMessageIdAuthorizedIsm which means OPStackIsm
const opStackIsm = OPStackIsm__factory.connect(address, this.provider);
try {
assert((await opStackIsm.moduleType()) === ModuleType.NULL);
await opStackIsm.VERIFIED_MASK_INDEX();
return {
address,
@ -247,11 +255,19 @@ export class EvmIsmReader implements IsmReader {
}
// no specific properties, must be Test ISM
const testIsm = TestIsm__factory.connect(address, this.provider);
assert((await testIsm.moduleType()) === ModuleType.NULL);
return {
address,
type: IsmType.TEST_ISM,
};
}
assertModuleType(
moduleType: ModuleType,
expectedModuleType: ModuleType,
): void {
assert(
moduleType === expectedModuleType,
`expected module type to be ${expectedModuleType}, got ${moduleType}`,
);
}
}

@ -302,7 +302,10 @@ export class MultisigMetadataBuilder implements MetadataBuilder {
metadata.signatures.forEach((signature) => {
const encodedSignature = joinSignature(signature);
assert(fromHexString(encodedSignature).byteLength === SIGNATURE_LENGTH);
assert(
fromHexString(encodedSignature).byteLength === SIGNATURE_LENGTH,
'Invalid signature length',
);
encoded += strip0x(encodedSignature);
});

@ -59,7 +59,7 @@ abstract class TokenDeployer<
} else if (isNativeConfig(config)) {
return config.scale ? [config.scale, config.mailbox] : [config.mailbox];
} else if (isSyntheticConfig(config)) {
assert(config.decimals); // decimals must be defined by this point
assert(config.decimals, 'decimals is undefined for config'); // decimals must be defined by this point
return [config.decimals, config.mailbox];
} else {
throw new Error('Unknown token type when constructing arguments');

@ -1,8 +1,8 @@
export function assert<T>(
predicate: T,
errorMessage?: string,
errorMessage: string,
): asserts predicate {
if (!predicate) {
throw new Error(errorMessage ?? 'Error');
throw new Error(errorMessage);
}
}

Loading…
Cancel
Save