فهرست منبع

[Xc admin] centralize some things (#527)

* Checkpoint

* Checkpoint

* Prettify

* Fix typo

* Move bpf upgradable loader

* Add file
guibescos 2 سال پیش
والد
کامیت
fdb2c5e012

+ 54 - 12
governance/xc-admin/packages/xc-admin-cli/src/index.ts

@@ -4,22 +4,26 @@ import {
   TransactionInstruction,
   SYSVAR_RENT_PUBKEY,
   SYSVAR_CLOCK_PUBKEY,
+  AccountMeta,
 } from "@solana/web3.js";
 import { program } from "commander";
 import { PythCluster } from "@pythnetwork/client/lib/cluster";
 import { getPythClusterApiUrl } from "@pythnetwork/client/lib/cluster";
-import { AnchorError, AnchorProvider, Program } from "@coral-xyz/anchor";
+import { AnchorProvider, Program } from "@coral-xyz/anchor";
 import fs from "fs";
 import SquadsMesh from "@sqds/mesh";
 import NodeWallet from "@coral-xyz/anchor/dist/cjs/nodewallet";
-import { proposeInstructions } from "xc-admin-common";
-
-const PROGRAM_AUTHORITY_ESCROW = new PublicKey(
-  "escMHe7kSqPcDHx4HU44rAHhgdTLBZkUrU39aN8kMcL"
-);
-const BPF_UPGRADABLE_LOADER = new PublicKey(
-  "BPFLoaderUpgradeab1e11111111111111111111111"
-);
+import {
+  BPF_UPGRADABLE_LOADER,
+  getMultisigCluster,
+  getProposalInstructions,
+  isRemoteCluster,
+  mapKey,
+  MultisigParser,
+  PROGRAM_AUTHORITY_ESCROW,
+  proposeInstructions,
+  WORMHOLE_ADDRESS,
+} from "xc-admin-common";
 
 const mutlisigCommand = (name: string, description: string) =>
   program
@@ -58,7 +62,11 @@ mutlisigCommand(
     const current: PublicKey = new PublicKey(options.current);
     const vault: PublicKey = new PublicKey(options.vault);
 
-    const squad = SquadsMesh.endpoint(getPythClusterApiUrl(cluster), wallet);
+    const isRemote = isRemoteCluster(cluster);
+    const squad = SquadsMesh.endpoint(
+      getPythClusterApiUrl(getMultisigCluster(cluster)),
+      wallet
+    );
     const msAccount = await squad.getMultisig(vault);
     const vaultAuthority = squad.getAuthorityPDA(
       msAccount.publicKey,
@@ -73,6 +81,7 @@ mutlisigCommand(
         AnchorProvider.defaultOptions()
       )
     );
+
     const programAuthorityEscrow = new Program(
       programAuthorityEscrowIdl!,
       PROGRAM_AUTHORITY_ESCROW,
@@ -91,14 +100,20 @@ mutlisigCommand(
       .accept()
       .accounts({
         currentAuthority: current,
-        newAuthority: vaultAuthority,
+        newAuthority: mapKey(vaultAuthority),
         programAccount: programId,
         programDataAccount,
         bpfUpgradableLoader: BPF_UPGRADABLE_LOADER,
       })
       .instruction();
 
-    await proposeInstructions(squad, vault, [proposalInstruction], false);
+    await proposeInstructions(
+      squad,
+      vault,
+      [proposalInstruction],
+      isRemote,
+      WORMHOLE_ADDRESS[getMultisigCluster(cluster)]
+    );
   });
 
 mutlisigCommand("upgrade-program", "Upgrade a program from a buffer")
@@ -150,4 +165,31 @@ mutlisigCommand("upgrade-program", "Upgrade a program from a buffer")
     await proposeInstructions(squad, vault, [proposalInstruction], false);
   });
 
+program
+  .command("parse-transaction")
+  .description("Parse a transaction sitting in the multisig")
+  .requiredOption("-c, --cluster <network>", "solana cluster to use")
+  .requiredOption("-t, --transaction <pubkey>", "path to the operations key")
+  .action(async (options: any) => {
+    const cluster = options.cluster;
+    const transaction: PublicKey = new PublicKey(options.transaction);
+    const squad = SquadsMesh.endpoint(
+      getPythClusterApiUrl(cluster),
+      new NodeWallet(new Keypair())
+    );
+    const onChainInstructions = await getProposalInstructions(
+      squad,
+      await squad.getTransaction(new PublicKey(transaction))
+    );
+    const parser = MultisigParser.fromCluster(cluster);
+    const parsed = onChainInstructions.map((ix) =>
+      parser.parseInstruction({
+        programId: ix.programId,
+        data: ix.data as Buffer,
+        keys: ix.keys as AccountMeta[],
+      })
+    );
+    console.log(JSON.stringify(parsed, null, 2));
+  });
+
 program.parse();

+ 9 - 0
governance/xc-admin/packages/xc-admin-common/src/bpf_upgradable_loader.ts

@@ -0,0 +1,9 @@
+import { PublicKey } from "@solana/web3.js";
+
+export const PROGRAM_AUTHORITY_ESCROW = new PublicKey(
+  "escMHe7kSqPcDHx4HU44rAHhgdTLBZkUrU39aN8kMcL"
+);
+
+export const BPF_UPGRADABLE_LOADER = new PublicKey(
+  "BPFLoaderUpgradeab1e11111111111111111111111"
+);

+ 23 - 0
governance/xc-admin/packages/xc-admin-common/src/cluster.ts

@@ -0,0 +1,23 @@
+import { PythCluster } from "@pythnetwork/client/lib/cluster";
+import { Cluster } from "@solana/web3.js";
+
+/**
+ * Return whether the cluster is governed remotely or not. For example Pythnet is governed remotely by a mainnet multisig.
+ */
+export function isRemoteCluster(cluster: PythCluster) {
+  return cluster == "pythnet" || cluster == "pythtest";
+}
+
+/**
+ * For cluster that are governed remotely (ex : Pythnet from Mainnet) return the network where the multisig lives
+ */
+export function getMultisigCluster(cluster: PythCluster): Cluster | "localnet" {
+  switch (cluster) {
+    case "pythnet":
+      return "mainnet-beta";
+    case "pythtest":
+      return "devnet";
+    default:
+      return cluster;
+  }
+}

+ 3 - 0
governance/xc-admin/packages/xc-admin-common/src/index.ts

@@ -3,3 +3,6 @@ export * from "./propose";
 export * from "./governance_payload";
 export * from "./wormhole";
 export * from "./multisig_transaction";
+export * from "./cluster";
+export * from "./remote_executor";
+export * from "./bpf_upgradable_loader";

+ 20 - 0
governance/xc-admin/packages/xc-admin-common/src/remote_executor.ts

@@ -0,0 +1,20 @@
+import { PublicKey } from "@solana/web3.js";
+
+/**
+ * Address of the remote executor (same on all networks)
+ */
+export const REMOTE_EXECUTOR_ADDRESS = new PublicKey(
+  "exe6S3AxPVNmy46L4Nj6HrnnAVQUhwyYzMSNcnRn3qq"
+);
+
+/**
+ * Map key to the key that a remote executor will use when it receives a message from `key`
+ * @param key the key to map
+ * @returns the key that the remote executor will use
+ */
+export function mapKey(key: PublicKey): PublicKey {
+  return PublicKey.findProgramAddressSync(
+    [Buffer.from("EXECUTOR_KEY"), key.toBytes()],
+    REMOTE_EXECUTOR_ADDRESS
+  )[0];
+}

+ 2 - 6
governance/xc-admin/packages/xc-admin-frontend/components/tabs/AddRemovePublishers.tsx

@@ -9,14 +9,10 @@ import { WalletModalButton } from '@solana/wallet-adapter-react-ui'
 import { PublicKey, TransactionInstruction } from '@solana/web3.js'
 import { Fragment, useContext, useEffect, useState } from 'react'
 import toast from 'react-hot-toast'
-import { proposeInstructions } from 'xc-admin-common'
+import { proposeInstructions, getMultisigCluster } from 'xc-admin-common'
 import { ClusterContext } from '../../contexts/ClusterContext'
 import { usePythContext } from '../../contexts/PythContext'
-import {
-  getMultisigCluster,
-  SECURITY_MULTISIG,
-  useMultisig,
-} from '../../hooks/useMultisig'
+import { SECURITY_MULTISIG, useMultisig } from '../../hooks/useMultisig'
 import { capitalizeFirstLetter } from '../../utils/capitalizeFirstLetter'
 import ClusterSwitch from '../ClusterSwitch'
 import Modal from '../common/Modal'

+ 6 - 10
governance/xc-admin/packages/xc-admin-frontend/components/tabs/UpdatePermissions.tsx

@@ -16,14 +16,14 @@ import {
 import copy from 'copy-to-clipboard'
 import { useContext, useEffect, useState } from 'react'
 import toast from 'react-hot-toast'
-import { proposeInstructions } from 'xc-admin-common'
-import { ClusterContext } from '../../contexts/ClusterContext'
-import { usePythContext } from '../../contexts/PythContext'
 import {
+  proposeInstructions,
   getMultisigCluster,
-  UPGRADE_MULTISIG,
-  useMultisig,
-} from '../../hooks/useMultisig'
+  BPF_UPGRADABLE_LOADER,
+} from 'xc-admin-common'
+import { ClusterContext } from '../../contexts/ClusterContext'
+import { usePythContext } from '../../contexts/PythContext'
+import { UPGRADE_MULTISIG, useMultisig } from '../../hooks/useMultisig'
 import CopyIcon from '../../images/icons/copy.inline.svg'
 import { capitalizeFirstLetter } from '../../utils/capitalizeFirstLetter'
 import ClusterSwitch from '../ClusterSwitch'
@@ -53,10 +53,6 @@ const DEFAULT_DATA: UpdatePermissionsProps[] = [
   },
 ]
 
-const BPF_UPGRADABLE_LOADER = new PublicKey(
-  'BPFLoaderUpgradeab1e11111111111111111111111'
-)
-
 const columnHelper = createColumnHelper<UpdatePermissionsProps>()
 
 const defaultColumns = [

+ 1 - 12
governance/xc-admin/packages/xc-admin-frontend/hooks/useMultisig.ts

@@ -4,21 +4,10 @@ import { Cluster, Connection, PublicKey } from '@solana/web3.js'
 import SquadsMesh from '@sqds/mesh'
 import { TransactionAccount } from '@sqds/mesh/lib/types'
 import { useContext, useEffect, useRef, useState } from 'react'
-import { getProposals } from 'xc-admin-common'
+import { getMultisigCluster, getProposals } from 'xc-admin-common'
 import { ClusterContext } from '../contexts/ClusterContext'
 import { pythClusterApiUrls } from '../utils/pythClusterApiUrl'
 
-export function getMultisigCluster(cluster: PythCluster): Cluster | 'localnet' {
-  switch (cluster) {
-    case 'pythnet':
-      return 'mainnet-beta'
-    case 'pythtest':
-      return 'devnet'
-    default:
-      return cluster
-  }
-}
-
 export const UPGRADE_MULTISIG: Record<Cluster | 'localnet', PublicKey> = {
   'mainnet-beta': new PublicKey('FVQyHcooAtThJ83XFrNnv74BcinbRH3bRmfFamAHBfuj'),
   testnet: new PublicKey('FVQyHcooAtThJ83XFrNnv74BcinbRH3bRmfFamAHBfuj'),