Skip to content

Commit 4638f44

Browse files
authored
Merge pull request #437 from kleros/chore/deploy
Chore/deploy
2 parents b69f059 + d400265 commit 4638f44

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+1534
-598
lines changed

docker-compose.yml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
services:
2+
validator:
3+
build:
4+
context: .
5+
dockerfile: ./validator-cli/Dockerfile
6+
command: yarn start --saveSnapshot
7+
env_file:
8+
- path: ./validator-cli/.env
9+
required: true
10+
restart: unless-stopped
11+
networks:
12+
- vea-network
13+
14+
relayer:
15+
build:
16+
context: .
17+
dockerfile: ./relayer-cli/Dockerfile
18+
env_file:
19+
- path: ./relayer-cli/.env
20+
required: true
21+
restart: unless-stopped
22+
networks:
23+
- vea-network
24+
networks:
25+
vea-network:

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
],
2727
"packageManager": "yarn@4.6.0",
2828
"volta": {
29-
"node": "22.14.0",
29+
"node": "24.4.0",
3030
"yarn": "4.6.0"
3131
},
3232
"devDependencies": {

relayer-cli/.env.dist

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,20 @@ PRIVATE_KEY=
66
SENDER_ADDRESSES_DEVNET=0x906dE43dBef27639b1688Ac46532a16dc07Ce410,0x123456789abcdef123456789abcdef1234567890
77
SENDER_ADDRESSES_TESTNET=0x0000000000000000000000000000000000000000
88
SENDER_ADDRESS_MAINNET=
9+
# Hashi sender addresses, zero address to allow all senders and enable hashi executor
10+
SENDER_ADDRESSES_HASHI=0x0000000000000000000000000000000000000000
911

1012
RPC_CHIADO=https://rpc.chiadochain.net
1113
RPC_SEPOLIA=
14+
RPC_ARBITRUM_SEPOLIA=
15+
RPC_STORY=
16+
RPC_ARBITRUM_ONE=
1217

13-
VEAOUTBOX_CHAINS=11155111,10200
18+
# Comma separated list of chain IDs where VeaOutbox is deployed
19+
VEAOUTBOX_CHAINS=11155111
1420

21+
# Comma separated list of chain pairs of sourceChainId-targetChainId for Hashi routes
22+
HASHI_CHAINS=421614-11155111,421614-10200,1514-42161
1523

1624
# Subgraph endpoint, Example: "85918/vea-inbox-arb-sepolia-devnet/version/latest"
1725
RELAYER_SUBGRAPH="61738/vea-inbox-arb-sepolia/version/latest"
@@ -22,6 +30,3 @@ TRANSACTION_BATCHER_CONTRACT_CHIADO=0xcC0a08D4BCC5f91ee9a1587608f7a2975EA75d73
2230

2331
# Ensure the path ends with a trailing slash ("/")
2432
STATE_DIR="/home/user/vea/relayer-cli/state/"
25-
26-
# Hashi Executor enabler
27-
HASHI_EXECUTOR_ENABLED=true

relayer-cli/Dockerfile

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
#
2+
# Builder image
3+
#
4+
5+
# Node version for Vea
6+
FROM node:24.4-alpine AS relayer-build
7+
8+
# Yarn version for Vea
9+
ARG YARN_VERSION=4.6.0
10+
RUN corepack enable \
11+
&& corepack prepare "yarn@${YARN_VERSION}" --activate
12+
13+
USER node
14+
WORKDIR /home/node/monorepo
15+
16+
#
17+
# Dependencies installation step.
18+
#
19+
20+
# Global monorepo dependencies
21+
COPY --chown=node:node ./.yarn/releases/ ./.yarn/releases/
22+
COPY --chown=node:node package.json yarn.lock .yarnrc.yml ./
23+
24+
#
25+
# Packages dependencies
26+
#
27+
COPY --chown=node:node ./relayer-cli/package.json relayer-cli/
28+
COPY --chown=node:node ./contracts/package.json contracts/
29+
30+
# We skip the `yarn cache clean` after install to speed up subsequent installs
31+
# (mostly the yarn workspace focus)
32+
RUN --mount=type=cache,id=yarn-cache,target=/home/node/monorepo/.yarn,uid=1000,gid=1000 \
33+
YARN_IGNORE_PATH=1 yarn install
34+
35+
#
36+
# Source code copy step.
37+
#
38+
COPY --chown=node:node relayer-cli ./relayer-cli
39+
COPY --chown=node:node contracts ./contracts
40+
41+
#
42+
# Build step to generate contract artifacts and typechain types
43+
#
44+
RUN [ -d contracts/typechain-types ] && echo "TypeChain present, skipping build" || yarn workspace @kleros/vea-contracts build
45+
RUN yarn workspaces focus @kleros/vea-relayer-cli
46+
47+
48+
49+
# ----------------------------------------------------------------------------------------------------
50+
# ----------------------------------------------------------------------------------------------------
51+
# ----------------------------------------------------------------------------------------------------
52+
53+
54+
#
55+
# Deployable image
56+
#
57+
# This is the final layer that will be deployed and run
58+
59+
# Node version for all Vea
60+
FROM node:24.4-alpine AS relayer
61+
62+
# Yarn version for all Vea
63+
ARG YARN_VERSION=4.6.0
64+
RUN corepack enable \
65+
&& corepack prepare "yarn@${YARN_VERSION}" --activate
66+
67+
USER root
68+
RUN mkdir -p /home/node/monorepo/.yarn && chown -R node:node /home/node/monorepo
69+
70+
71+
USER node
72+
WORKDIR /home/node/monorepo
73+
74+
# Copy only the necessary files from the builder stage
75+
COPY --from=relayer-build --link /home/node/monorepo/contracts/typechain-types ./contracts/typechain-types
76+
COPY --from=relayer-build --link /home/node/monorepo/contracts/deployments ./contracts/deployments
77+
78+
# Copy the globally required files and the service workspace
79+
COPY --from=relayer-build --link /home/node/monorepo/node_modules /home/node/monorepo/node_modules
80+
COPY --from=relayer-build --link \
81+
/home/node/monorepo/.yarnrc.yml \
82+
/home/node/monorepo/yarn.lock \
83+
/home/node/monorepo/package.json \
84+
./
85+
86+
COPY --from=relayer-build --link /home/node/monorepo/relayer-cli ./relayer-cli
87+
88+
WORKDIR /home/node/monorepo/relayer-cli
89+
90+
RUN mkdir -p /home/node/monorepo/relayer-cli/state && chown -R node:node /home/node/monorepo/relayer-cli/state
91+
ENV YARN_IGNORE_PATH=1
92+
CMD ["yarn", "start-relayer"]

relayer-cli/README.md

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,21 @@
1-
# bots
1+
# Relayer bot
22

33
A collection of bots for the Vea relayers.
44

5-
- src/devnetRelayExample.ts
5+
- src/relayer.ts
66

7-
# pm2
7+
# docker
88

9-
`pm2 start`
9+
`docker compose build relayer`
1010

11-
Runs a relayer for all messages sent through example gateway contracts.
11+
`docker compose up relayer`
12+
13+
Runs a relayer for all messages sent through VeaInbox contracts.
14+
15+
# `env` config
16+
17+
- `VEAOUTBOX_CHAINS`: to chose the chains to execute messages on.
18+
19+
- Address params: used to execute for specific sender addresses or everyone if zero address is provided.
20+
21+
- `SENDER_ADDRESSES`: pass zero address to allow all senders and relayer or executor for hashi.

relayer-cli/package.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,19 @@
1313
"start-relayer": "ts-node ./src/relayer.ts"
1414
},
1515
"dependencies": {
16-
"@kleros/vea-contracts": "workspace:^",
1716
"@typechain/ethers-v6": "^0.5.1",
1817
"dotenv": "^16.4.5",
18+
"ethers": "^6.13.5",
19+
"graphql": "^16.8.1",
20+
"graphql-request": "^6.1.0",
21+
"pino": "^10.1.0",
1922
"pm2": "^6.0.5",
2023
"typescript": "^4.9.5"
2124
},
2225
"devDependencies": {
2326
"@types/jest": "^29.5.14",
2427
"jest": "^29.7.0",
28+
"pino-pretty": "13.1.2",
2529
"ts-jest": "^29.2.5",
2630
"ts-node": "^10.9.2"
2731
}

relayer-cli/src/consts/bridgeRoutes.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
// File for handling contants and configurations
22
require("dotenv").config();
3-
import veaInboxArbToEthDevnet from "@kleros/vea-contracts/deployments/arbitrumSepolia/VeaInboxArbToEthDevnet.json";
4-
import veaOutboxArbToEthDevnet from "@kleros/vea-contracts/deployments/sepolia/VeaOutboxArbToEthDevnet.json";
5-
import veaInboxArbToEthTestnet from "@kleros/vea-contracts/deployments/arbitrumSepolia/VeaInboxArbToEthTestnet.json";
6-
import veaOutboxArbToEthTestnet from "@kleros/vea-contracts/deployments/sepolia/VeaOutboxArbToEthTestnet.json";
3+
import veaInboxArbToEthDevnet from "../../../contracts/deployments/arbitrumSepolia/VeaInboxArbToEthDevnet.json";
4+
import veaOutboxArbToEthDevnet from "../../../contracts/deployments/sepolia/VeaOutboxArbToEthDevnet.json";
5+
import veaInboxArbToEthTestnet from "../../../contracts/deployments/arbitrumSepolia/VeaInboxArbToEthTestnet.json";
6+
import veaOutboxArbToEthTestnet from "../../../contracts/deployments/sepolia/VeaOutboxArbToEthTestnet.json";
77

8-
import veaInboxArbToGnosisDevnet from "@kleros/vea-contracts/deployments/arbitrumSepolia/VeaInboxArbToGnosisDevnet.json";
9-
import veaOutboxArbToGnosisDevnet from "@kleros/vea-contracts/deployments/chiado/VeaOutboxArbToGnosisDevnet.json";
8+
import veaInboxArbToGnosisDevnet from "../../../contracts/deployments/arbitrumSepolia/VeaInboxArbToGnosisDevnet.json";
9+
import veaOutboxArbToGnosisDevnet from "../../../contracts/deployments/chiado/VeaOutboxArbToGnosisDevnet.json";
1010

11-
import veaInboxArbToGnosisTestnet from "@kleros/vea-contracts/deployments/arbitrumSepolia/VeaInboxArbToGnosisTestnet.json";
12-
import veaOutboxArbToGnosisTestnet from "@kleros/vea-contracts/deployments/chiado/VeaOutboxArbToGnosisTestnet.json";
11+
import veaInboxArbToGnosisTestnet from "../../../contracts/deployments/arbitrumSepolia/VeaInboxArbToGnosisTestnet.json";
12+
import veaOutboxArbToGnosisTestnet from "../../../contracts/deployments/chiado/VeaOutboxArbToGnosisTestnet.json";
1313

1414
interface IBridge {
1515
chainId: number;

relayer-cli/src/relayer.ts

Lines changed: 35 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -15,29 +15,42 @@ import { initialize as initializeEmitter } from "./utils/logger";
1515
import { BotEvents } from "./utils/botEvents";
1616
import { getEpochPeriod, Network } from "./consts/bridgeRoutes";
1717
import { runHashiExecutor } from "./utils/hashi";
18+
import { sendHeartbeat } from "./utils/heartbeat";
1819

1920
interface RelayerConfig {
2021
networkConfigs: RelayerNetworkConfig[];
2122
shutdownManager: ShutdownManager;
2223
emitter: EventEmitter;
2324
}
2425

26+
const HASHI_CYCLE_TIME_MS = 5 * 60 * 1000; // 5 minutes
27+
2528
/**
2629
* Start the relayer
2730
* @param config.networkConfigs The network configurations retrieved from the env.
2831
* @param config.shutdownManager The shutdown manager
2932
* @param config.emitter The event emitter
3033
*/
3134
export async function start({ networkConfigs, shutdownManager, emitter }: RelayerConfig) {
35+
const HEARTBEAT_URL = process.env.HEARTBEAT_URL;
36+
await sendHeartbeat("started", HEARTBEAT_URL);
3237
initializeEmitter(emitter);
33-
let delayAmount = 7200 * 1000; // 2 hours in ms
38+
const executeTimes: number[] = networkConfigs.map(() => 0);
3439
while (!shutdownManager.getIsShuttingDown()) {
35-
for (const networkConfig of networkConfigs) {
36-
delayAmount = await processNetworkConfig(networkConfig, shutdownManager, emitter, delayAmount);
40+
let executeTime: number = HASHI_CYCLE_TIME_MS + Date.now();
41+
await sendHeartbeat("running", HEARTBEAT_URL);
42+
for (let i = 0; i < networkConfigs.length; i++) {
43+
if (executeTimes[i] > Date.now()) {
44+
continue;
45+
}
46+
executeTimes[i] = await processNetworkConfig(networkConfigs[i], shutdownManager, emitter, executeTimes[i]);
47+
executeTime = Math.min(executeTime, executeTimes[i]);
3748
}
38-
emitter.emit(BotEvents.WAITING, delayAmount);
39-
await delay(delayAmount);
49+
const delayMs = executeTime - Date.now();
50+
emitter.emit(BotEvents.WAITING, delayMs);
51+
await delay(delayMs);
4052
}
53+
await sendHeartbeat("stopped", HEARTBEAT_URL);
4154
}
4255

4356
/**
@@ -54,37 +67,40 @@ async function processNetworkConfig(
5467
emitter: EventEmitter,
5568
currentDelay: number
5669
): Promise<number> {
57-
const { chainId, network, senders } = networkConfig;
58-
emitter.emit(BotEvents.STARTED, chainId, network);
70+
const { chainId, network, senders, sourceChainId } = networkConfig;
71+
const logNetwork = sourceChainId ? `${sourceChainId}->${chainId} Hashi` : network;
72+
emitter.emit(BotEvents.STARTED, chainId, logNetwork);
5973
const maxBatchSize = 10; // 10 messages per batch
6074

6175
await setupExitHandlers(chainId, shutdownManager, network, emitter);
6276

63-
let { nonce, hashiNonce } = await initializeNonces(chainId, network, emitter);
64-
if (nonce == null) return currentDelay;
65-
66-
const hashiExecutorEnabled = process.env.HASHI_EXECUTOR_ENABLED === "true";
67-
if (hashiExecutorEnabled) {
77+
let { nonce, hashiBlockNumber } = await initializeNonces(chainId, network, emitter);
78+
if (sourceChainId) {
6879
// Execute messages on Hashi
69-
hashiNonce = await runHashiExecutor({ chainId, network, nonce: hashiNonce, emitter });
80+
hashiBlockNumber = await runHashiExecutor({
81+
sourceChainId,
82+
targetChainId: chainId,
83+
network,
84+
blockNumber: hashiBlockNumber,
85+
emitter,
86+
});
87+
await updateStateFile(chainId, Math.floor(Date.now() / 1000), nonce, hashiBlockNumber, network, emitter);
88+
return Date.now() + HASHI_CYCLE_TIME_MS;
7089
}
71-
7290
const toRelayAll = senders[0] === ethers.ZeroAddress;
7391
nonce = toRelayAll
7492
? await relayBatch({ chainId, network, nonce, maxBatchSize, emitter })
7593
: await relayAllFrom(chainId, network, nonce, senders, emitter);
7694

77-
if (nonce == null) return currentDelay;
78-
79-
await updateStateFile(chainId, Math.floor(Date.now() / 1000), nonce, hashiNonce, network, emitter);
95+
await updateStateFile(chainId, Math.floor(Date.now() / 1000), nonce, hashiBlockNumber, network, emitter);
8096

8197
if (network === Network.DEVNET) {
82-
return 1000 * 10; // 10 seconds for devnet
98+
return Date.now() + 1000 * 60 * 2; // 2 min for devnet
8399
} else {
84100
const currentTS = Math.floor(Date.now() / 1000);
85101
const epochPeriod = getEpochPeriod(chainId);
86102
const timeLeft = (epochPeriod - (Math.floor(currentTS / 1000) % epochPeriod)) * 1000 + 100 * 1000;
87-
return Math.min(currentDelay, timeLeft);
103+
return Date.now() + timeLeft;
88104
}
89105
}
90106

@@ -97,6 +113,5 @@ if (require.main === module) {
97113
shutdownManager,
98114
emitter,
99115
};
100-
101116
start(testnetRelayerConfig);
102117
}

relayer-cli/src/utils/botEvents.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,5 @@ export enum BotEvents {
2323
HASHI_EXECUTED = "hashi_executed",
2424
HASHI_BATCH_TXN = "hashi_batch_txn",
2525
HASHI_EXECUTION_FAILED = "hashi_execution_failed",
26+
HASHI_NOT_CONFIGURED = "hashi_not_configured",
2627
}

relayer-cli/src/utils/ethers.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
VeaOutboxArbToGnosis__factory,
88
VeaOutboxArbToGnosisDevnet__factory,
99
TransactionBatcher__factory,
10-
} from "@kleros/vea-contracts/typechain-types";
10+
} from "../../../contracts/typechain-types";
1111
import { getBridgeConfig, Network } from "../consts/bridgeRoutes";
1212

1313
function getWallet(privateKey: string, web3ProviderURL: string): Wallet {

0 commit comments

Comments
 (0)