Skip to content

Commit

Permalink
Simplify core interface
Browse files Browse the repository at this point in the history
  • Loading branch information
yorhodes committed May 5, 2024
1 parent 9e03c11 commit 9551c34
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 62 deletions.
1 change: 0 additions & 1 deletion solidity/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
"exports": {
".": "./dist/index.js",
"./mailbox": "./dist/contracts/Mailbox.js",
"./merkle": "./dist/contracts/hooks/MerkleTreeHook.js",
"./buildArtifact.js": "./dist/buildArtifact.js",
"./buildArtifact.json": "./dist/buildArtifact.json",
"./contracts": "./contracts"
Expand Down
4 changes: 2 additions & 2 deletions typescript/cli/src/status/message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export async function checkMessageStatus({
chainAddresses,
context.multiProvider,
);

const mailbox = core.getContracts(destination).mailbox;
log(`Checking status of message ${messageId} on ${destination}`);
const delivered = await mailbox.delivered(messageId);
Expand All @@ -65,8 +66,7 @@ export async function checkMessageStatus({
.getProvider(origin)
.getTransactionReceipt(dispatchTx);

const messages = core.getDispatchedMessages(dispatchTxReceipt);
const tx = await core.relayMessage(messages[0], dispatchTxReceipt);
const tx = await core.relayMessage(dispatchTxReceipt);
logGreen(
`Message ${messageId} was relayed in ${context.multiProvider.getExplorerTxUrl(
destination,
Expand Down
66 changes: 23 additions & 43 deletions typescript/sdk/src/core/HyperlaneCore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { ethers } from 'ethers';
import type { TransactionReceipt as ViemTxReceipt } from 'viem';

import {
IInterchainSecurityModule__factory,
IMessageRecipient__factory,
MailboxClient__factory,
Mailbox__factory,
Expand Down Expand Up @@ -217,8 +216,9 @@ export class HyperlaneCore extends HyperlaneApp<CoreFactories> {
}

async relayMessage(
message: DispatchedMessage,
dispatchTx: TransactionReceipt,
index = 0,
message = HyperlaneCore.getDispatchedMessages(dispatchTx)[index],
): Promise<ethers.ContractReceipt> {
assert(
this.multiProvider.hasChain(message.parsed.origin) &&
Expand All @@ -229,6 +229,12 @@ export class HyperlaneCore extends HyperlaneApp<CoreFactories> {
const destinationChain = this.getDestination(message);
const mailbox = this.getContracts(destinationChain).mailbox;

const isDelivered = await mailbox.delivered(message.id);
if (isDelivered) {
this.logger.debug(`Message ${message.id} already delivered`);
return this.getProcessedReceipt(message);
}

const recipient = IMessageRecipient__factory.connect(
bytes32ToAddress(message.parsed.recipient),
mailbox.provider,
Expand All @@ -241,46 +247,20 @@ export class HyperlaneCore extends HyperlaneApp<CoreFactories> {
{ from: mailbox.address },
);

const recipientIsm = await this.getRecipientIsmAddress(message);
const ism = IInterchainSecurityModule__factory.connect(
recipientIsm,
mailbox.provider,
);

return pollAsync(
async () => {
this.logger.debug(
{ message, recipientIsm },
`Building recipient ISM metadata`,
);
const metadata = await this.buildMetadata(message, dispatchTx);

this.logger.debug(
{ message, metadata },
`Simulating recipient ISM verification`,
);
const verified = await ism.callStatic.verify(metadata, message.message);
assert(verified, 'ISM verification failed');

const isDelivered = await mailbox.delivered(message.id);
if (isDelivered) {
this.logger.debug(`Message ${message.id} already delivered`);
return this.getProcessedReceipt(message);
}

this.logger.info(
{ message, metadata },
`Relaying message ${message.id} to ${destinationChain}`,
);

return this.multiProvider.handleTx(
destinationChain,
mailbox.process(metadata, message.message),
);
},
const metadata = await pollAsync(
() => this.buildMetadata(message, dispatchTx),
5 * 1000, // every 5 seconds
12, // 12 attempts
);

this.logger.info(
{ message, metadata },
`Relaying message ${message.id} to ${destinationChain}`,
);
return this.multiProvider.handleTx(
destinationChain,
mailbox.process(metadata, message.message),
);
}

async relay(
Expand Down Expand Up @@ -316,12 +296,11 @@ export class HyperlaneCore extends HyperlaneApp<CoreFactories> {
this.multiProvider.tryGetChainName(destination);
if (destinationChain) {
this.logger.info(
{ chain: originChain, sender, destination, recipient },
{ originChain, sender, destinationChain, recipient },
`Observed message from ${originChain} to ${destinationChain} attempting to relay`,
);
const dispatched = HyperlaneCore.parseDispatchedMessage(message);
const receipt = await event.getTransactionReceipt();
await this.relayMessage(dispatched, receipt);
const dispatchReceipt = await event.getTransactionReceipt();
await this.relayMessage(dispatchReceipt);
}
},
);
Expand Down Expand Up @@ -413,6 +392,7 @@ export class HyperlaneCore extends HyperlaneApp<CoreFactories> {
messageId: string,
): Promise<TransactionReceipt> {
const mailbox = this.contractsMap[originChain].mailbox;
// TODO: scan and chunk if necessary
const filter = mailbox.filters.DispatchId(messageId);
const matchingEvents = await mailbox.queryFilter(filter);
if (matchingEvents.length === 0) {
Expand Down
36 changes: 20 additions & 16 deletions typescript/sdk/src/ism/metadata/multisig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { TransactionReceipt } from '@ethersproject/providers';
import { joinSignature, splitSignature } from 'ethers/lib/utils.js';

import { MerkleTreeHook__factory } from '@hyperlane-xyz/core';
import type { InsertedIntoTreeEvent } from '@hyperlane-xyz/core/merkle';
import {
Address,
Checkpoint,
Expand Down Expand Up @@ -115,19 +114,25 @@ export class MultisigMetadataBuilder
const originChain = this.core.multiProvider.getChainName(match.origin);
const s3Validators = await this.s3Validators(originChain, validators);

const checkpointPromises = await Promise.allSettled(
const results = await Promise.allSettled(
s3Validators.map((v) => v.getCheckpoint(match.index)),
);
const checkpoints = checkpointPromises
const checkpoints = results
.filter(
(p): p is PromiseFulfilledResult<S3CheckpointWithId | undefined> =>
p.status === 'fulfilled',
(result): result is PromiseFulfilledResult<S3CheckpointWithId> =>
result.status === 'fulfilled' && result.value !== undefined,
)
.map((p) => p.value)
.filter((v): v is S3CheckpointWithId => v !== undefined);
.map((result) => result.value);

this.logger.debug({ checkpoints }, 'Fetched checkpoints');

if (checkpoints.length < validators.length) {
this.logger.debug(
{ checkpoints, validators, match },
`Found ${checkpoints.length} checkpoints out of ${validators.length} validators`,
);
}

const matchingCheckpoints = checkpoints.filter(
({ value }) =>
eqAddress(
Expand Down Expand Up @@ -162,24 +167,23 @@ export class MultisigMetadataBuilder
'Merkle proofs are not yet supported',
);

const merkleTree = context.hook.address;

const matchingInsertion = context.dispatchTx.logs
.filter((l) => eqAddressEvm(l.address, context.hook.address))
.map(
(l) =>
MerkleTreeInterface.parseLog(l) as unknown as InsertedIntoTreeEvent,
)
.find((e) => e.args.messageId === message.id);
.filter((log) => eqAddressEvm(log.address, merkleTree))
.map((log) => MerkleTreeInterface.parseLog(log))
.find((event) => event.args.messageId === message.id);

assert(
matchingInsertion,
`No merkle tree insertion of ${message.id} to ${context.hook.address} found in dispatch tx`,
`No merkle tree insertion of ${message.id} to ${merkleTree} found in dispatch tx`,
);
this.logger.debug({ matchingInsertion }, 'Found matching insertion event');

const checkpoints = await this.getS3Checkpoints(context.ism.validators, {
origin: message.parsed.origin,
merkleTree: context.hook.address,
messageId: message.id,
merkleTree,
index: matchingInsertion.args.index,
});
assert(
Expand All @@ -193,7 +197,7 @@ export class MultisigMetadataBuilder
);

const signatures = checkpoints
.map((c) => c.signature)
.map((checkpoint) => checkpoint.signature)
.slice(0, context.ism.threshold);

this.logger.debug(
Expand Down

0 comments on commit 9551c34

Please sign in to comment.