Skip to content

Commit

Permalink
Implement single-run relayer
Browse files Browse the repository at this point in the history
  • Loading branch information
ethanfrey committed Mar 10, 2021
1 parent 3278c7c commit 787a14a
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 4 deletions.
48 changes: 44 additions & 4 deletions src/binary/ibc-relayer/commands/start.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import path from 'path';

import { Link } from '../../../lib/link';
import { registryFile } from '../../constants';
import { loadAndValidateApp } from '../../utils/load-and-validate-app';
import { loadAndValidateRegistry } from '../../utils/load-and-validate-registry';
import { resolveRequiredOption } from '../../utils/options/resolve-required-option';
import { resolveHomeOption } from '../../utils/options/shared/resolve-home-option';
import { resolveKeyFileOption } from '../../utils/options/shared/resolve-key-file-option';
import { resolveMnemonicOption } from '../../utils/options/shared/resolve-mnemonic-option';
import { signingClient } from '../../utils/signing-client';

type Flags = {
interactive: boolean;
Expand All @@ -19,14 +21,23 @@ type Flags = {
destConnection?: string;
};

// TODO: do we want to make this a flag?
type LoopOptions = {
runOnce: boolean;
// number of seconds old the client on chain A can be
maxAgeA: number;
// number of seconds old the client on chain B can be
maxAgeB: number;
};

type Options = {
home: string;
src: string;
dest: string;
mnemonic: string;
srcConnection: string;
destConnection: string;
};
} & LoopOptions;

export async function start(flags: Flags) {
const home = resolveHomeOption({ homeFlag: flags.home });
Expand Down Expand Up @@ -68,12 +79,17 @@ export async function start(flags: Flags) {
mnemonic,
srcConnection,
destConnection,
// TODO: make configurable
runOnce: true,
// once per day
maxAgeA: 86400,
maxAgeB: 86400,
};

run(options);
await run(options);
}

function run(options: Options) {
async function run(options: Options) {
const registryFilePath = path.join(options.home, registryFile);
const { chains } = loadAndValidateRegistry(registryFilePath);
const srcChain = chains[options.src];
Expand All @@ -85,5 +101,29 @@ function run(options: Options) {
throw new Error('dest chain not found in registry');
}

console.log('ibc-relayer start with options:', options);
const nodeA = await signingClient(srcChain, options.mnemonic);
const nodeB = await signingClient(destChain, options.mnemonic);
const link = await Link.createWithExistingConnections(
nodeA,
nodeB,
options.srcConnection,
options.destConnection
);

await relayerLoop(link, options);
}

async function relayerLoop(link: Link, options: LoopOptions) {
if (!options.runOnce) {
throw new Error('Loop is not supported yet, try runOnce = true');
}

// TODO: fill this in with real data (how far back do we start querying... where do we store state?)
let nextRelay = {};
nextRelay = await link.checkAndRelayPacketsAndAcks(nextRelay);
console.log(nextRelay);

// ensure the headers are up to date (only submits if old and we didn't just update them above)
await link.updateClientIfStale('A', options.maxAgeB);
await link.updateClientIfStale('B', options.maxAgeA);
}
6 changes: 6 additions & 0 deletions src/binary/types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { GasPrice } from '@cosmjs/launchpad';

export type Chain = {
chain_id: string;
prefix: string;
Expand All @@ -19,3 +21,7 @@ export type AppConfig = {
mnemonic?: string;
keyFile?: string;
};

export function feeDenom(chain: Chain): string {
return GasPrice.fromString(chain.gas_price).denom;
}
33 changes: 33 additions & 0 deletions src/binary/utils/signing-client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { stringToPath } from '@cosmjs/crypto';
import { GasPrice } from '@cosmjs/launchpad';
import { DirectSecp256k1HdWallet } from '@cosmjs/proto-signing';

import { IbcClient, IbcClientOptions } from '../../lib/ibcclient';
import { Logger } from '../../lib/logger';
import { Chain } from '../types';

export async function signingClient(
chain: Chain,
mnemonic: string,
logger?: Logger
): Promise<IbcClient> {
const hdPath = chain.hd_path ? stringToPath(chain.hd_path) : undefined;
const signer = await DirectSecp256k1HdWallet.fromMnemonic(
mnemonic,
hdPath,
chain.prefix
);
const { address } = (await signer.getAccounts())[0];
const options: IbcClientOptions = {
prefix: chain.prefix,
gasPrice: GasPrice.fromString(chain.gas_price),
logger,
};
const client = await IbcClient.connectWithSigner(
chain.rpc[0],
signer,
address,
options
);
return client;
}

0 comments on commit 787a14a

Please sign in to comment.