Skip to content

Commit 4f2c85b

Browse files
committed
scripts: get solana missed message accounts
1 parent ae5f336 commit 4f2c85b

File tree

1 file changed

+72
-0
lines changed

1 file changed

+72
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import * as dotenv from 'dotenv';
2+
dotenv.config();
3+
4+
import { CONTRACTS } from '@certusone/wormhole-sdk/lib/cjs/utils/consts';
5+
import { Connection } from '@solana/web3.js';
6+
import axios from 'axios';
7+
import ora from 'ora';
8+
import { RPCS_BY_CHAIN } from '../src/consts';
9+
import { isLegacyMessage, normalizeCompileInstruction } from '../src/utils/solana';
10+
11+
// This script finds the message accounts which correspond to solana misses
12+
13+
(async () => {
14+
const now = new Date();
15+
now.setHours(now.getHours() - 2);
16+
const twoHoursAgo = now.toISOString();
17+
try {
18+
let log = ora('Fetching Solana misses').start();
19+
const response = await axios.get(
20+
'https://europe-west3-wormhole-315720.cloudfunctions.net/missing-vaas'
21+
);
22+
const solanaTxHashes = response.data[1].messages
23+
.filter((m: any) => m.timestamp < twoHoursAgo)
24+
.map((m: any) => m.txHash);
25+
log.succeed();
26+
log = ora('Fetching message accounts').start();
27+
const connection = new Connection(RPCS_BY_CHAIN.solana!, 'finalized');
28+
const txs = await connection.getTransactions(solanaTxHashes, {
29+
maxSupportedTransactionVersion: 0,
30+
});
31+
// TODO: share with Solana watcher?
32+
const accounts = [];
33+
let errorCount = 0;
34+
for (const tx of txs) {
35+
if (!tx) {
36+
errorCount++;
37+
} else {
38+
const message = tx.transaction.message;
39+
const accountKeys = isLegacyMessage(message)
40+
? message.accountKeys
41+
: message.staticAccountKeys;
42+
const programIdIndex = accountKeys.findIndex(
43+
(i) => i.toBase58() === CONTRACTS.MAINNET.solana.core
44+
);
45+
const instructions = message.compiledInstructions;
46+
const innerInstructions =
47+
tx.meta?.innerInstructions?.flatMap((i) =>
48+
i.instructions.map(normalizeCompileInstruction)
49+
) || [];
50+
const whInstructions = innerInstructions
51+
.concat(instructions)
52+
.filter((i) => i.programIdIndex === programIdIndex);
53+
for (const instruction of whInstructions) {
54+
// skip if not postMessage instruction
55+
const instructionId = instruction.data;
56+
if (instructionId[0] !== 0x01) continue;
57+
58+
accounts.push(accountKeys[instruction.accountKeyIndexes[1]]);
59+
}
60+
}
61+
}
62+
log.succeed();
63+
for (const a of accounts) {
64+
console.log(`send-observation-request 1 ${a}`);
65+
}
66+
console.log(
67+
`Fetch ${accounts.length} accounts from ${solanaTxHashes.length} transactions with ${errorCount} errors`
68+
);
69+
} catch (e) {
70+
console.error(e);
71+
}
72+
})();

0 commit comments

Comments
 (0)