瀏覽代碼

Add sample script that syncs governance vaas for a contract (#989)

Mohammad Amin Khashkhashi Moghaddam 2 年之前
父節點
當前提交
ff77561960
共有 1 個文件被更改,包括 105 次插入0 次删除
  1. 105 0
      contract_manager/scripts/sync_governance_vaas.ts

+ 105 - 0
contract_manager/scripts/sync_governance_vaas.ts

@@ -0,0 +1,105 @@
+import yargs from "yargs";
+import { hideBin } from "yargs/helpers";
+import { DefaultStore } from "../src/store";
+import { PriceServiceConnection } from "@pythnetwork/price-service-client";
+import { SubmittedWormholeMessage, Vault } from "../src/governance";
+import { parseVaa } from "@certusone/wormhole-sdk";
+import { decodeGovernancePayload } from "xc_admin_common";
+
+const parser = yargs(hideBin(process.argv))
+  .usage(
+    "Tries to execute all vaas on a contract.\n" +
+      "Useful for recently deployed contracts.\n" +
+      "Usage: $0 --contract <contract_id> --private-key <private-key>"
+  )
+  .options({
+    contract: {
+      type: "string",
+      demandOption: true,
+      desc: "Contract to execute governance vaas for",
+    },
+    "private-key": {
+      type: "string",
+      demandOption: true,
+      desc: "Private key to sign the transactions executing the governance VAAs. Hex format, without 0x prefix.",
+    },
+    offset: {
+      type: "number",
+      desc: "Starting sequence number to use, if not provided will start from contract last executed governance sequence number",
+    },
+  });
+
+async function main() {
+  const argv = await parser.argv;
+  const contract = DefaultStore.contracts[argv.contract];
+  if (!contract) {
+    throw new Error(`Contract ${argv.contract} not found`);
+  }
+  const governanceSource = await contract.getGovernanceDataSource();
+  const mainnetVault =
+    DefaultStore.vaults[
+      "mainnet-beta_FVQyHcooAtThJ83XFrNnv74BcinbRH3bRmfFamAHBfuj"
+    ];
+  const devnetVault =
+    DefaultStore.vaults["devnet_6baWtW1zTUVMSJHJQVxDUXWzqrQeYBr6mu31j3bTKwY3"];
+  let matchedVault: Vault;
+  if (
+    (await devnetVault.getEmitter()).toBuffer().toString("hex") ===
+    governanceSource.emitterAddress
+  ) {
+    console.log("devnet multisig matches governance source");
+    matchedVault = devnetVault;
+  } else if (
+    (await mainnetVault.getEmitter()).toBuffer().toString("hex") ===
+    governanceSource.emitterAddress
+  ) {
+    console.log("mainnet multisig matches governance source");
+    matchedVault = mainnetVault;
+  } else {
+    throw new Error(
+      "can not find a multisig that matches the governance source of the contract"
+    );
+  }
+  let lastExecuted = await contract.getLastExecutedGovernanceSequence();
+  console.log("last executed governance sequence", lastExecuted);
+  if (argv.offset && argv.offset > lastExecuted) {
+    console.log("skipping to offset", argv.offset);
+    lastExecuted = argv.offset - 1;
+  }
+  console.log("Starting from sequence number", lastExecuted);
+  while (true) {
+    const submittedWormholeMessage = new SubmittedWormholeMessage(
+      await matchedVault.getEmitter(),
+      lastExecuted + 1,
+      matchedVault.cluster
+    );
+    let vaa: Buffer;
+    try {
+      vaa = await submittedWormholeMessage.fetchVaa();
+    } catch (e) {
+      console.log(e);
+      console.log("no vaa found for sequence", lastExecuted + 1);
+      break;
+    }
+    const parsedVaa = parseVaa(vaa);
+    const action = decodeGovernancePayload(parsedVaa.payload);
+    if (!action) {
+      console.log("can not decode vaa, skipping");
+    } else if (
+      action.targetChainId === "unset" ||
+      contract.getChain().wormholeChainName === action.targetChainId
+    ) {
+      console.log("executing vaa", lastExecuted + 1);
+      await contract.executeGovernanceInstruction(argv["private-key"], vaa);
+    } else {
+      console.log(
+        `vaa is not for this chain (${
+          contract.getChain().wormholeChainName
+        } != ${action.targetChainId}, skipping`
+      );
+    }
+    lastExecuted++;
+  }
+}
+
+main();