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

Fixes for multi-protocol Kathy #2738

Merged
merged 29 commits into from
Oct 4, 2023
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
18f8324
Fixes for kathy
jmrossy Sep 17, 2023
db8751d
Merge branch 'main' into rossy/enable-sealevel-kathy
jmrossy Sep 18, 2023
54b65c1
Fix bugs in SealevelCoreAdapter
jmrossy Sep 18, 2023
1511294
Improve stat collection to handle cross-protocol msgs
jmrossy Sep 18, 2023
bf9d736
Re-enable actual env config for Kathy
jmrossy Sep 18, 2023
9d78585
Merge branch 'main' into rossy/enable-sealevel-kathy
jmrossy Sep 28, 2023
6e908e9
Add helloworld router addresses
jmrossy Sep 28, 2023
ee08546
Update helloworld docker tags
jmrossy Sep 28, 2023
f876489
Use GCP keys instead of AWS for sealevel kathy
jmrossy Sep 28, 2023
52e928b
Update docker tags to latest
jmrossy Sep 28, 2023
5e951d4
Fix external secrets
tkporter Sep 29, 2023
fb55dfb
Merge branch 'rossy/enable-sealevel-kathy' of github.com:abacus-netwo…
tkporter Sep 29, 2023
08008d1
Update getCloudAgentKey logic
jmrossy Sep 29, 2023
5837a7c
Merge branch 'rossy/enable-sealevel-kathy' of github.com:hyperlane-xy…
jmrossy Sep 29, 2023
d0f0870
Ensure GCP key exists
tkporter Sep 29, 2023
4a32b96
Update tags
jmrossy Sep 29, 2023
a22554c
Merge branch 'rossy/enable-sealevel-kathy' of github.com:abacus-netwo…
tkporter Sep 29, 2023
36b1d5f
Small key fixes
tkporter Sep 29, 2023
66cc484
Remove dead getAddressForKey code
jmrossy Sep 29, 2023
5479fa3
Add key fetching for sol chains
jmrossy Sep 29, 2023
e239f0d
Various fixes to get Kathy running locally
tkporter Sep 29, 2023
1980b07
Merge branch 'main' into rossy/enable-sealevel-kathy
jmrossy Oct 3, 2023
eb70b2e
Fix build error
jmrossy Oct 3, 2023
58dc62b
Run prettier
jmrossy Oct 3, 2023
0af0f30
Run prettier again, skipping lintstaged
jmrossy Oct 3, 2023
00ded33
Update helloworld docker tag
jmrossy Oct 3, 2023
7154780
Fix helloworld circular dependency & envAddresses
tkporter Oct 4, 2023
f99a473
Update helloworld docker tags
jmrossy Oct 4, 2023
67a7342
Fix external secret getting kathy key secret
tkporter Oct 4, 2023
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
4 changes: 2 additions & 2 deletions typescript/helloworld/src/app/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export type StatCounts = {
sent: number | bigint;
received: number | bigint;
sent: number;
received: number;
};
16 changes: 2 additions & 14 deletions typescript/helloworld/src/multiProtocolApp/evmAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import {
} from '@hyperlane-xyz/sdk';
import { Address } from '@hyperlane-xyz/utils';

import { StatCounts } from '../app/types';
import { HelloWorld, HelloWorld__factory } from '../types';

import { IHelloWorldAdapter } from './types';
Expand Down Expand Up @@ -55,22 +54,11 @@ export class EvmHelloWorldAdapter
return { transaction: tx, type: ProviderType.EthersV5 };
}

async channelStats(
destination: ChainName,
destinationMailbox: Address,
): Promise<StatCounts> {
const originDomain = this.multiProvider.getDomainId(this.chainName);
async sentStat(destination: ChainName): Promise<number> {
const destinationDomain = this.multiProvider.getDomainId(destination);
const originContract = this.getConnectedContract();
const sent = await originContract.sentTo(destinationDomain);
const destinationProvider =
this.multiProvider.getEthersV5Provider(destination);
const destinationContract = HelloWorld__factory.connect(
destinationMailbox,
destinationProvider,
);
const received = await destinationContract.sentTo(originDomain);
return { sent: sent.toNumber(), received: received.toNumber() };
return sent.toNumber();
}

override getConnectedContract(): HelloWorld {
Expand Down
14 changes: 9 additions & 5 deletions typescript/helloworld/src/multiProtocolApp/multiProtocolApp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,15 @@ export class HelloMultiProtocolApp extends MultiProtocolRouterApp<
);
}

channelStats(origin: ChainName, destination: ChainName): Promise<StatCounts> {
return this.adapter(origin).channelStats(
destination,
this.addresses[destination].mailbox,
);
async channelStats(
origin: ChainName,
destination: ChainName,
): Promise<StatCounts> {
const [sent, received] = await Promise.all([
this.adapter(origin).sentStat(destination),
this.adapter(destination).sentStat(origin),
]);
return { sent, received };
}

async stats(): Promise<ChainMap<ChainMap<StatCounts>>> {
Expand Down
15 changes: 6 additions & 9 deletions typescript/helloworld/src/multiProtocolApp/sealevelAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@ import {
} from '@hyperlane-xyz/sdk';
import { Address, Domain } from '@hyperlane-xyz/utils';

import { StatCounts } from '../app/types';

import { IHelloWorldAdapter } from './types';

export class SealevelHelloWorldAdapter
Expand Down Expand Up @@ -164,21 +162,20 @@ export class SealevelHelloWorldAdapter
);
}

async channelStats(_destination: ChainName): Promise<StatCounts> {
async sentStat(destination: ChainName): Promise<number> {
const destinationDomain = this.multiProvider.getDomainId(destination);
const data = await this.getAccountInfo();
return { sent: data.sent, received: data.received };
return Number(data.sent_to.get(destinationDomain) || 0);
}

async getAccountInfo(): Promise<HelloWorldData> {
const address = this.addresses.router;
const connection = this.getProvider();

const msgRecipientPda = this.deriveMessageRecipientPda(address);
const accountInfo = await connection.getAccountInfo(msgRecipientPda);
const pda = this.deriveProgramStoragePDA(address);
const accountInfo = await connection.getAccountInfo(pda);
if (!accountInfo)
throw new Error(
`No account info found for ${msgRecipientPda.toBase58()}}`,
);
throw new Error(`No account info found for ${pda.toBase58()}}`);

const accountData = deserializeUnchecked(
HelloWorldDataSchema,
Expand Down
9 changes: 1 addition & 8 deletions typescript/helloworld/src/multiProtocolApp/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ import {
} from '@hyperlane-xyz/sdk';
import { Address } from '@hyperlane-xyz/utils';

import { StatCounts } from '../app/types';

export interface IHelloWorldAdapter extends IRouterAdapter {
populateSendHelloTx: (
destination: ChainName,
Expand All @@ -15,10 +13,5 @@ export interface IHelloWorldAdapter extends IRouterAdapter {
sender: Address,
) => Promise<TypedTransaction>;

// TODO break apart into separate origin + destination methods to
// handle case where origin/dest protocols differ
channelStats: (
destination: ChainName,
destinationMailbox: Address,
) => Promise<StatCounts>;
sentStat: (destination: ChainName) => Promise<number>;
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,8 @@
},
"sepolia": {
"router": "0x5d56B8a669F50193b54319442c6EEE5edD662381"
},
"solanadevnet": {
"router": "CXQX54kdkU5GqdRJjCmHpwHfEMgFb5SeBmMWntP2Ds7J"
}
}
12 changes: 8 additions & 4 deletions typescript/infra/scripts/helloworld/kathy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,12 @@ import { DeployEnvironment } from '../../src/config/environment';
import { Role } from '../../src/roles';
import { startMetricsServer } from '../../src/utils/metrics';
import { assertChain, diagonalize, sleep } from '../../src/utils/utils';
import { getAddressesForKey, getArgs, withContext } from '../utils';
import {
getAddressesForKey,
getArgs,
getEnvironmentConfig,
withContext,
} from '../utils';

import { getHelloWorldMultiProtocolApp } from './utils';

Expand Down Expand Up @@ -160,9 +165,8 @@ async function main(): Promise<boolean> {
startMetricsServer(metricsRegister);
debug('Starting up', { environment });

// TODO (Rossy) remove getCoreConfigStub and re-enable getEnvironmentConfig
// const coreConfig = getEnvironmentConfig(environment);
const coreConfig = getCoreConfigStub(environment);
const coreConfig = getEnvironmentConfig(environment);
// const coreConfig = getCoreConfigStub(environment);
jmrossy marked this conversation as resolved.
Show resolved Hide resolved

const { app, core, igp, multiProvider, keys } =
await getHelloWorldMultiProtocolApp(
Expand Down
18 changes: 12 additions & 6 deletions typescript/infra/scripts/helloworld/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ import {
chainMetadata,
filterAddressesToProtocol,
hyperlaneEnvironments,
hyperlaneEnvironmentsWithSealevel,
igpFactories,
} from '@hyperlane-xyz/sdk';
import { hyperlaneEnvironmentsWithSealevel } from '@hyperlane-xyz/sdk/src';
import { ProtocolType, objMerge } from '@hyperlane-xyz/utils';
import { ProtocolType, objMap } from '@hyperlane-xyz/utils';

import { Contexts } from '../../config/contexts';
import { EnvironmentConfig } from '../../src/config';
Expand Down Expand Up @@ -62,6 +62,9 @@ export async function getHelloWorldMultiProtocolApp(
connectionType,
);
const sdkEnvName = deployEnvToSdkEnv[coreConfig.environment];
const envAddresses = hyperlaneEnvironments[sdkEnvName];
const envAddressesWithSealevel =
hyperlaneEnvironmentsWithSealevel[sdkEnvName];
const keys = await coreConfig.getKeys(keyContext, keyRole);

const helloworldConfig = getHelloWorldConfig(coreConfig, context);
Expand All @@ -76,13 +79,17 @@ export async function getHelloWorldMultiProtocolApp(
}

const core = MultiProtocolCore.fromAddressesMap(
hyperlaneEnvironmentsWithSealevel[sdkEnvName],
envAddressesWithSealevel,
multiProtocolProvider,
);

const routersAndMailboxes = objMerge(
core.chainMap,
const routersAndMailboxes = objMap(
helloworldConfig.addresses,
(chain, addresses) => ({
router: addresses.router,
// @ts-ignore allow loosely typed chain name to index env addresses
mailbox: envAddressesWithSealevel[chain].mailbox,
}),
);
const app = new HelloMultiProtocolApp(
multiProtocolProvider,
Expand All @@ -92,7 +99,6 @@ export async function getHelloWorldMultiProtocolApp(
// TODO we need a MultiProtocolIgp
// Using an standard IGP for just evm chains for now
// Unfortunately this requires hacking surgically around certain addresses
const envAddresses = hyperlaneEnvironments[sdkEnvName];
const filteredAddresses = filterAddressesToProtocol(
envAddresses,
ProtocolType.Ethereum,
Expand Down
23 changes: 17 additions & 6 deletions typescript/sdk/src/core/adapters/SealevelCoreAdapter.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import { PublicKey } from '@solana/web3.js';

import { Address, HexString, pollAsync } from '@hyperlane-xyz/utils';
import {
Address,
HexString,
ensure0x,
pollAsync,
strip0x,
} from '@hyperlane-xyz/utils';

import { BaseSealevelAdapter } from '../../app/MultiProtocolApp';
import { MultiProtocolProvider } from '../../providers/MultiProtocolProvider';
Expand Down Expand Up @@ -35,14 +41,13 @@ export class SealevelCoreAdapter
`Unsupported provider type for SealevelCoreAdapter ${sourceTx.type}`,
);
}
const receipt = sourceTx.receipt;
const logs = receipt.meta?.logMessages;
const logs = sourceTx.receipt.meta?.logMessages;
if (!logs)
throw new Error('Transaction logs required to check message delivery');
const parsedLogs = SealevelCoreAdapter.parseMessageDispatchLogs(logs);
if (!parsedLogs.length) throw new Error('Message dispatch log not found');
return parsedLogs.map(({ destination, messageId }) => ({
messageId: Buffer.from(messageId, 'hex').toString('hex'),
messageId: ensure0x(messageId),
destination: this.multiProvider.getChainName(destination),
}));
}
Expand Down Expand Up @@ -144,10 +149,16 @@ export class SealevelCoreAdapter

static deriveMailboxMessageProcessedPda(
mailboxProgramId: string | PublicKey,
messageId: string,
messageId: HexString,
): PublicKey {
return super.derivePda(
['hyperlane', '-', 'processed_message', Buffer.from(messageId, 'hex')],
[
'hyperlane',
'-',
'processed_message',
'-',
Buffer.from(strip0x(messageId), 'hex'),
],
mailboxProgramId,
);
}
Expand Down
16 changes: 8 additions & 8 deletions typescript/utils/src/addresses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,14 +135,14 @@ export function isValidTransactionHashSealevel(input: string) {
return SEALEVEL_TX_HASH_REGEX.test(input);
}

export function isValidTransactionHash(input: string, protocol?: ProtocolType) {
return routeAddressUtil(
isValidTransactionHashEvm,
isValidTransactionHashSealevel,
false,
input,
protocol,
);
export function isValidTransactionHash(input: string, protocol: ProtocolType) {
if (protocol === ProtocolType.Ethereum) {
return isValidTransactionHashEvm(input);
} else if (protocol === ProtocolType.Sealevel) {
return isValidTransactionHashSealevel(input);
} else {
return false;
}
}

export function isZeroishAddress(address: Address) {
Expand Down