Skip to content

Commit 996257b

Browse files
authored
Merge branch 'dev' into fix/handle-sent-snapshots
2 parents a2d97c5 + 159d672 commit 996257b

File tree

15 files changed

+1057
-84
lines changed

15 files changed

+1057
-84
lines changed

relayer-cli/.env.dist

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,7 @@ TRANSACTION_BATCHER_CONTRACT_SEPOLIA=0xe7953da7751063d0a41ba727c32c762d3523ade8
2121
TRANSACTION_BATCHER_CONTRACT_CHIADO=0xcC0a08D4BCC5f91ee9a1587608f7a2975EA75d73
2222

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

relayer-cli/src/consts/bridgeRoutes.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,11 @@ interface IBridge {
1717
epochPeriod: number;
1818
veaContracts: { [key in Network]: VeaContracts };
1919
batcherAddress: string;
20+
rpcInbox: string;
2021
rpcOutbox: string;
22+
yahoAddress?: string; // Hashi (Yaru) contract address
23+
yaruAddress?: string; // Hashi (Yaru) contract address
24+
hashiAddress?: string; // Hashi (Yaru) contract address
2125
}
2226

2327
type VeaContracts = {
@@ -60,15 +64,23 @@ const bridges: { [chainId: number]: IBridge } = {
6064
epochPeriod: 7200,
6165
veaContracts: arbToEthContracts,
6266
batcherAddress: process.env.TRANSACTION_BATCHER_CONTRACT_SEPOLIA!,
67+
rpcInbox: process.env.RPC_ARBITRUM_SEPOLIA!,
6368
rpcOutbox: process.env.RPC_SEPOLIA!,
69+
yahoAddress: "0xDbdF80c87f414fac8342e04D870764197bD3bAC7", // Hashi (Yaho) contract address on Arbitrum Sepolia
70+
yaruAddress: "0x231e48AAEaAC6398978a1dBA4Cd38fcA208Ec391", // Hashi (Yaru) contract address on Sepolia
71+
hashiAddress: "0x78E4ae687De18B3B71Ccd0e8a3A76Fed49a02A02", // Hashi (Hashi) contract address on Sepolia
6472
},
6573
10200: {
6674
chainId: 10200,
6775
chain: "chiado",
6876
epochPeriod: 3600,
6977
veaContracts: arbToGnosisContracts,
7078
batcherAddress: process.env.TRANSACTION_BATCHER_CONTRACT_CHIADO!,
79+
rpcInbox: process.env.RPC_ARBITRUM_SEPOLIA!,
7180
rpcOutbox: process.env.RPC_CHIADO!,
81+
yahoAddress: "0xDbdF80c87f414fac8342e04D870764197bD3bAC7", // Hashi (Yaho) contract address on Arbitrum Sepolia
82+
yaruAddress: "0x639c26C9F45C634dD14C599cBAa27363D4665C53", // Hashi (Yaru) contract address on Chiado
83+
hashiAddress: "0x78E4ae687De18B3B71Ccd0e8a3A76Fed49a02A02", // Hashi (Hashi) contract address on Chiado
7284
},
7385
};
7486

relayer-cli/src/relayer.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { EventEmitter } from "node:events";
33
import { ethers } from "ethers";
44
import { relayBatch, relayAllFrom } from "./utils/relay";
55
import {
6-
initialize as initializeNonce,
6+
initialize as initializeNonces,
77
updateStateFile,
88
delay,
99
setupExitHandlers,
@@ -14,6 +14,7 @@ import {
1414
import { initialize as initializeEmitter } from "./utils/logger";
1515
import { BotEvents } from "./utils/botEvents";
1616
import { getEpochPeriod, Network } from "./consts/bridgeRoutes";
17+
import { runHashiExecutor } from "./utils/hashi";
1718

1819
interface RelayerConfig {
1920
networkConfigs: RelayerNetworkConfig[];
@@ -59,17 +60,23 @@ async function processNetworkConfig(
5960

6061
await setupExitHandlers(chainId, shutdownManager, network, emitter);
6162

62-
let nonce = await initializeNonce(chainId, network, emitter);
63+
let { nonce, hashiNonce } = await initializeNonces(chainId, network, emitter);
6364
if (nonce == null) return currentDelay;
6465

66+
const hashiExecutorEnabled = process.env.HASHI_EXECUTOR_ENABLED === "true";
67+
if (hashiExecutorEnabled) {
68+
// Execute messages on Hashi
69+
hashiNonce = await runHashiExecutor({ chainId, network, nonce: hashiNonce, emitter });
70+
}
71+
6572
const toRelayAll = senders[0] === ethers.ZeroAddress;
6673
nonce = toRelayAll
6774
? await relayBatch({ chainId, network, nonce, maxBatchSize, emitter })
6875
: await relayAllFrom(chainId, network, nonce, senders, emitter);
6976

7077
if (nonce == null) return currentDelay;
7178

72-
await updateStateFile(chainId, Math.floor(Date.now() / 1000), nonce, network, emitter);
79+
await updateStateFile(chainId, Math.floor(Date.now() / 1000), nonce, hashiNonce, network, emitter);
7380

7481
if (network === Network.DEVNET) {
7582
return 1000 * 10; // 10 seconds for devnet

relayer-cli/src/utils/botEvents.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,10 @@ export enum BotEvents {
1717
RELAY_BATCH = "relay_batch",
1818
RELAY_ALL_FROM = "relay_all_from",
1919
MESSAGE_EXECUTION_FAILED = "message_execution_failed",
20+
21+
// Hashi executor
22+
EXECUTING_HASHI = "executing_hashi",
23+
HASHI_EXECUTED = "hashi_executed",
24+
HASHI_BATCH_TXN = "hashi_batch_txn",
25+
HASHI_EXECUTION_FAILED = "hashi_execution_failed",
2026
}
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
import request from "graphql-request";
2+
import { VeaOutboxArbToEth, VeaOutboxArbToGnosis } from "@kleros/vea-contracts/typechain-types";
3+
4+
async function getVeaMsgTrnx(nonce: number, inboxAddress: string) {
5+
console.log(`Fetching transaction hashes for nonce ${nonce} from inbox ${inboxAddress}`);
6+
try {
7+
const subgraph = process.env.RELAYER_SUBGRAPH;
8+
const query = `{messageSents(first: 1, where: {nonce: ${nonce}, inbox: "${inboxAddress}"}) {
9+
id
10+
transactionHash
11+
}}`;
12+
const result = (await request(`https://api.studio.thegraph.com/query/${subgraph}`, query)) as {
13+
messageSents: { id: string; transactionHash: string }[];
14+
};
15+
return result.messageSents.map((trnx) => trnx.transactionHash);
16+
} catch (e) {
17+
console.log(e);
18+
return [];
19+
}
20+
}
21+
22+
interface SnapshotResponse {
23+
snapshotSaveds: Array<{ count: string }>;
24+
}
25+
/**
26+
* Get the count of the veaOutbox
27+
* @param veaOutbox The veaOutbox contract instance
28+
* @param chainId The chain id of the veaOutbox chain
29+
* @returns The count of the veaOutbox
30+
*/
31+
const getCount = async (veaOutbox: VeaOutboxArbToEth | VeaOutboxArbToGnosis, chainId: number): Promise<number> => {
32+
const subgraph = process.env.RELAYER_SUBGRAPH;
33+
const stateRoot = await veaOutbox.stateRoot();
34+
35+
const result = (await request(
36+
`https://api.studio.thegraph.com/query/${subgraph}`,
37+
`{
38+
snapshotSaveds(first: 1, where: { stateRoot: "${stateRoot}" }) {
39+
count
40+
}
41+
}`
42+
)) as SnapshotResponse;
43+
44+
if (result["snapshotSaveds"].length == 0) return 0;
45+
46+
return Number(result["snapshotSaveds"][0].count);
47+
};
48+
49+
interface MessageSent {
50+
nonce: number;
51+
}
52+
53+
interface MessageSentsResponse {
54+
messageSents: MessageSent[];
55+
}
56+
57+
/**
58+
* Get the nonces of messages sent by a given sender
59+
* @param chainId The chain id of the veaOutbox chain
60+
* @param nonce The nonce of the first message to relay
61+
* @param msgSender The address of the sender
62+
* @returns The nonces of the messages sent by the sender
63+
*/
64+
const getNonceFrom = async (chainId: number, inbox: string, nonce: number, msgSender: string) => {
65+
const subgraph = process.env.RELAYER_SUBGRAPH;
66+
67+
const result = (await request(
68+
`https://api.studio.thegraph.com/query/${subgraph}`,
69+
`{
70+
messageSents(
71+
first: 1000,
72+
where: {
73+
inbox: "${inbox}",
74+
nonce_gte: ${nonce},
75+
msgSender_: {id: "${msgSender.toLowerCase()}"}
76+
},
77+
orderBy: nonce,
78+
orderDirection: asc
79+
) {
80+
nonce
81+
}
82+
}`
83+
)) as MessageSentsResponse;
84+
85+
return result[`messageSents`].map((a: { nonce: string | number }) => Number(a.nonce));
86+
};
87+
88+
export { getVeaMsgTrnx, getCount, getNonceFrom };

0 commit comments

Comments
 (0)