sync_governance_vaas.ts 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. import yargs from "yargs";
  2. import { hideBin } from "yargs/helpers";
  3. import { parseVaa } from "@certusone/wormhole-sdk";
  4. import { decodeGovernancePayload } from "@pythnetwork/xc-admin-common";
  5. import { toPrivateKey } from "../src/core/base";
  6. import { SubmittedWormholeMessage, Vault } from "../src/node/utils/governance";
  7. import { DefaultStore } from "../src/node/utils/store";
  8. const parser = yargs(hideBin(process.argv))
  9. .usage(
  10. "Tries to execute all vaas on a contract.\n" +
  11. "Useful for recently deployed contracts.\n" +
  12. "Usage: $0 --contract <contract_id> --private-key <private-key>",
  13. )
  14. .options({
  15. contract: {
  16. type: "string",
  17. demandOption: true,
  18. desc: "Contract to execute governance vaas for",
  19. },
  20. "private-key": {
  21. type: "string",
  22. demandOption: true,
  23. desc: "Private key to sign the transactions executing the governance VAAs. Hex format, without 0x prefix.",
  24. },
  25. offset: {
  26. type: "number",
  27. desc: "Starting sequence number to use, if not provided will start from contract last executed governance sequence number",
  28. },
  29. });
  30. async function main() {
  31. const argv = await parser.argv;
  32. const contract = DefaultStore.contracts[argv.contract];
  33. if (!contract) {
  34. throw new Error(`Contract ${argv.contract} not found`);
  35. }
  36. const governanceSource = await contract.getGovernanceDataSource();
  37. const mainnetVault =
  38. DefaultStore.vaults[
  39. "mainnet-beta_FVQyHcooAtThJ83XFrNnv74BcinbRH3bRmfFamAHBfuj"
  40. ];
  41. const devnetVault =
  42. DefaultStore.vaults["devnet_6baWtW1zTUVMSJHJQVxDUXWzqrQeYBr6mu31j3bTKwY3"];
  43. let matchedVault: Vault;
  44. if (
  45. (await devnetVault.getEmitter()).toBuffer().toString("hex") ===
  46. governanceSource.emitterAddress
  47. ) {
  48. console.log("devnet multisig matches governance source");
  49. matchedVault = devnetVault;
  50. } else if (
  51. (await mainnetVault.getEmitter()).toBuffer().toString("hex") ===
  52. governanceSource.emitterAddress
  53. ) {
  54. console.log("mainnet multisig matches governance source");
  55. matchedVault = mainnetVault;
  56. } else {
  57. throw new Error(
  58. "can not find a multisig that matches the governance source of the contract",
  59. );
  60. }
  61. let lastExecuted = await contract.getLastExecutedGovernanceSequence();
  62. console.log("last executed governance sequence", lastExecuted);
  63. if (argv.offset && argv.offset > lastExecuted) {
  64. console.log("skipping to offset", argv.offset);
  65. lastExecuted = argv.offset - 1;
  66. }
  67. console.log("Starting from sequence number", lastExecuted);
  68. // eslint-disable-next-line no-constant-condition
  69. while (true) {
  70. const submittedWormholeMessage = new SubmittedWormholeMessage(
  71. await matchedVault.getEmitter(),
  72. lastExecuted + 1,
  73. matchedVault.cluster,
  74. );
  75. let vaa: Buffer;
  76. try {
  77. vaa = await submittedWormholeMessage.fetchVaa();
  78. } catch (e) {
  79. console.log(e);
  80. console.log("no vaa found for sequence", lastExecuted + 1);
  81. break;
  82. }
  83. const parsedVaa = parseVaa(vaa);
  84. const action = decodeGovernancePayload(parsedVaa.payload);
  85. if (!action) {
  86. console.log("can not decode vaa, skipping");
  87. } else if (
  88. action.targetChainId === "unset" ||
  89. contract.getChain().wormholeChainName === action.targetChainId
  90. ) {
  91. console.log("executing vaa", lastExecuted + 1);
  92. await contract.executeGovernanceInstruction(
  93. toPrivateKey(argv["private-key"]),
  94. vaa,
  95. );
  96. } else {
  97. console.log(
  98. `vaa is not for this chain (${
  99. contract.getChain().wormholeChainName
  100. } != ${action.targetChainId}, skipping`,
  101. );
  102. }
  103. lastExecuted++;
  104. }
  105. }
  106. main();