Explorar o código

Update dockerfile (#1041)

* Update dockerfile

* Drive by v4

* Reduce scope

* Revert dockerfile

* Revert dockerfile changes

* Cleanup the other dockerfile

* Remove contracts dir

* Remove old cli
guibescos %!s(int64=2) %!d(string=hai) anos
pai
achega
f7699bb6b0

+ 1 - 1
.github/workflows/lerna.yaml

@@ -7,7 +7,7 @@ jobs:
   test:
     runs-on: ubuntu-latest
     steps:
-      - uses: actions/checkout@v3
+      - uses: actions/checkout@v4
       - uses: actions/setup-node@v3
         with:
           node-version: 18

+ 0 - 178
governance/xc_admin/packages/xc_admin_cli/src/cli.ts

@@ -1,178 +0,0 @@
-import { program } from "commander";
-import { loadContractConfig, ContractType, SyncOp } from "xc_admin_common";
-import * as fs from "fs";
-
-// TODO: extract this configuration to a file
-const contractsConfig = [
-  {
-    type: ContractType.EvmPythUpgradable,
-    networkId: "arbitrum",
-    address: "0xff1a0f4744e8582DF1aE09D5611b887B6a12925C",
-  },
-  {
-    type: ContractType.EvmWormholeReceiver,
-    networkId: "canto",
-    address: "0x87047526937246727E4869C5f76A347160e08672",
-  },
-  {
-    type: ContractType.EvmPythUpgradable,
-    networkId: "canto",
-    address: "0x98046Bd286715D3B0BC227Dd7a956b83D8978603",
-  },
-  {
-    type: ContractType.EvmPythUpgradable,
-    networkId: "avalanche",
-    address: "0x4305FB66699C3B2702D4d05CF36551390A4c69C6",
-  },
-];
-
-const networksConfig = {
-  evm: {
-    optimism_goerli: {
-      url: `https://rpc.ankr.com/optimism_testnet`,
-    },
-    arbitrum: {
-      url: "https://arb1.arbitrum.io/rpc",
-    },
-    avalanche: {
-      url: "https://api.avax.network/ext/bc/C/rpc",
-    },
-    canto: {
-      url: "https://canto.gravitychain.io",
-    },
-  },
-};
-
-// TODO: we will need configuration of this stuff to decide which multisig to run.
-const multisigs = [
-  {
-    name: "",
-    wormholeNetwork: "mainnet",
-  },
-];
-
-program
-  .name("pyth_governance")
-  .description("CLI for governing Pyth contracts")
-  .version("0.1.0");
-
-program
-  .command("get")
-  .description("Find Pyth contracts matching the given search criteria")
-  .option("-n, --network <network-id>", "Find contracts on the given network")
-  .option("-a, --address <address>", "Find contracts with the given address")
-  .option("-t, --type <type-id>", "Find contracts of the given type")
-  .action(async (options: any) => {
-    const contracts = loadContractConfig(contractsConfig, networksConfig);
-
-    console.log(JSON.stringify(options));
-
-    const matches = [];
-    for (const contract of contracts) {
-      if (
-        (options.network === undefined ||
-          contract.networkId == options.network) &&
-        (options.address === undefined ||
-          contract.getAddress() == options.address) &&
-        (options.type === undefined || contract.type == options.type)
-      ) {
-        matches.push(contract);
-      }
-    }
-
-    for (const contract of matches) {
-      const state = await contract.getState();
-      console.log({
-        networkId: contract.networkId,
-        address: contract.getAddress(),
-        type: contract.type,
-        state: state,
-      });
-    }
-  });
-
-class Cache {
-  private path: string;
-
-  constructor(path: string) {
-    this.path = path;
-  }
-
-  private opFilePath(op: SyncOp): string {
-    return `${this.path}/${op.id()}.json`;
-  }
-
-  public readOpCache(op: SyncOp): Record<string, any> {
-    const path = this.opFilePath(op);
-    if (fs.existsSync(path)) {
-      return JSON.parse(fs.readFileSync(path).toString("utf-8"));
-    } else {
-      return {};
-    }
-  }
-
-  public writeOpCache(op: SyncOp, cache: Record<string, any>) {
-    fs.writeFileSync(this.opFilePath(op), JSON.stringify(cache));
-  }
-
-  public deleteCache(op: SyncOp) {
-    fs.rmSync(this.opFilePath(op));
-  }
-}
-
-program
-  .command("set")
-  .description("Set a configuration parameter for one or more Pyth contracts")
-  .option("-n, --network <network-id>", "Find contracts on the given network")
-  .option("-a, --address <address>", "Find contracts with the given address")
-  .option("-t, --type <type-id>", "Find contracts of the given type")
-  .argument("<fields...>", "Fields to set on the given contracts")
-  .action(async (fields, options: any, command) => {
-    const contracts = loadContractConfig(contractsConfig, networksConfig);
-
-    console.log(JSON.stringify(fields));
-    console.log(JSON.stringify(options));
-
-    const setters = fields.map((value: string) => value.split("="));
-
-    const matches = [];
-    for (const contract of contracts) {
-      if (
-        (options.network === undefined ||
-          contract.networkId == options.network) &&
-        (options.address === undefined ||
-          contract.getAddress() == options.address) &&
-        (options.type === undefined || contract.type == options.type)
-      ) {
-        matches.push(contract);
-      }
-    }
-
-    const ops = [];
-    for (const contract of matches) {
-      const state = await contract.getState();
-      // TODO: make a decent format for this
-      for (const [field, value] of setters) {
-        state[field] = value;
-      }
-
-      ops.push(...(await contract.sync(state)));
-    }
-
-    // TODO: extract constant
-    const cacheDir = "cache";
-    fs.mkdirSync(cacheDir, { recursive: true });
-    const cache = new Cache(cacheDir);
-
-    for (const op of ops) {
-      const opCache = cache.readOpCache(op);
-      const isDone = await op.run(opCache);
-      if (isDone) {
-        cache.deleteCache(op);
-      } else {
-        cache.writeOpCache(op, opCache);
-      }
-    }
-  });
-
-program.parse();

+ 0 - 1
governance/xc_admin/packages/xc_admin_common/package.json

@@ -23,7 +23,6 @@
     "@certusone/wormhole-sdk": "^0.9.22",
     "@coral-xyz/anchor": "^0.26.0",
     "@pythnetwork/client": "^2.17.0",
-    "@pythnetwork/pyth-sdk-solidity": "*",
     "@solana/buffer-layout": "^4.0.1",
     "@solana/web3.js": "^1.73.0",
     "@sqds/mesh": "^1.0.6",

+ 0 - 140
governance/xc_admin/packages/xc_admin_common/src/contracts/Contract.ts

@@ -1,140 +0,0 @@
-import { ChainId } from "../chains";
-import { ethers } from "ethers";
-import { PythGovernanceAction } from "../governance_payload";
-
-export enum ContractType {
-  Oracle,
-  EvmPythUpgradable,
-  EvmWormholeReceiver,
-}
-
-/**
- * A unique identifier for a blockchain. Note that we cannot use ChainId for this, as ChainId currently reuses
- * some ids across mainnet / testnet chains (e.g., ethereum goerli has the same id as ethereum mainnet).
- */
-export type NetworkId = string;
-
-/** A unique identifier for message senders across all wormhole networks. */
-export interface WormholeAddress {
-  emitter: string;
-  chainId: ChainId;
-  // which network this sender is on
-  network: WormholeNetwork;
-}
-export type WormholeNetwork = "mainnet" | "testnet";
-
-/**
- * A Contract is the basic unit of on-chain state that is managed by xc_admin.
- * Each contracts lives at a specific address of a specific network, and has a type
- * representing which of several known contract types (evm target chain, wormhole receiver, etc)
- * that it is.
- *
- * Contracts further expose a state representing values that can be modified by governance.
- * The fields of the state object vary depending on what type of contract this is.
- * Finally, contracts expose a sync method that generates the needed operations to bring the on-chain state
- * in sync with a provided desired state.
- */
-export interface Contract<State> {
-  type: ContractType;
-  networkId: NetworkId;
-  /** The address of the contract. The address may be written in different formats for different networks. */
-  getAddress(): string;
-
-  /** Get the on-chain state of all governance-controllable fields of this contract. */
-  getState(): Promise<State>;
-
-  /** Generate a set of operations that, if executed, will update the on-chain contract state to be `target`. */
-  sync(target: State): Promise<SyncOp[]>;
-}
-
-/**
- * An idempotent synchronization operation to update on-chain state. The operation may depend on
- * external approvals or actions to complete, in which case the operation will pause and need to
- * be resumed later.
- */
-export interface SyncOp {
-  /**
-   * A unique identifier for this operation. The id represents the content of the operation (e.g., "sets the X
-   * field to Y on contract Z"), so can be used to identify the "same" operation across multiple runs of this program.
-   */
-  id(): string;
-  /**
-   * Run this operation from a previous state (recorded in cache). The operation can modify cache
-   * to record progress, then returns true if the operation has completed. If this function returns false,
-   * it is waiting on an external operation to complete (e.g., a multisig transaction to be approved).
-   * Re-run this function again once that operation is completed to continue making progress.
-   *
-   * The caller of this function is responsible for preserving the contents of `cache` between calls to
-   * this function.
-   */
-  run(cache: Record<string, any>): Promise<boolean>;
-}
-
-export class SendGovernanceInstruction implements SyncOp {
-  private instruction: PythGovernanceAction;
-  private sender: WormholeAddress;
-  // function to submit the signed VAA to the target chain contract
-  private submitVaa: (vaa: string) => Promise<boolean>;
-
-  constructor(
-    instruction: PythGovernanceAction,
-    from: WormholeAddress,
-    submitVaa: (vaa: string) => Promise<boolean>
-  ) {
-    this.instruction = instruction;
-    this.sender = from;
-    this.submitVaa = submitVaa;
-  }
-
-  public id(): string {
-    // TODO: use a more understandable identifier (also this may not be unique)
-    return ethers.utils.sha256(this.instruction.encode());
-  }
-
-  public async run(cache: Record<string, any>): Promise<boolean> {
-    // FIXME: this implementation is temporary. replace with something like the commented out code below.
-    if (cache["multisigTx"] === undefined) {
-      cache["multisigTx"] = "fooooo";
-      return false;
-    }
-
-    if (cache["vaa"] === undefined) {
-      return false;
-    }
-
-    // VAA is guaranteed to be defined here
-    const vaa = cache["vaa"];
-
-    // assertVaaPayloadEquals(vaa, payload);
-
-    return await this.submitVaa(vaa);
-  }
-
-  /*
-  public async run(cache: Record<string,any>): Promise<boolean> {
-    if (cache["multisigTx"] === undefined) {
-      // Have not yet submitted this operation to the multisig.
-      const payload = this.instruction.serialize();
-      const txKey = vault.sendWormholeInstruction(payload);
-      cache["multisigTx"] = txKey;
-      return false;
-    }
-
-    if (cache["vaa"] === undefined) {
-      const vaa = await executeMultisigTxAndGetVaa(txKey, payloadHex);
-      if (vaa === undefined) {
-        return false;
-      }
-      cache["vaa"] = vaa;
-    }
-
-    // VAA is guaranteed to be defined here
-    const vaa = cache["vaa"];
-
-    assertVaaPayloadEquals(vaa, payload);
-
-    // await proxy.executeGovernanceInstruction("0x" + vaa);
-    await submitVaa(vaa);
-  }
-   */
-}

+ 0 - 96
governance/xc_admin/packages/xc_admin_common/src/contracts/EvmPythUpgradable.ts

@@ -1,96 +0,0 @@
-import {
-  Contract,
-  ContractType,
-  NetworkId,
-  SendGovernanceInstruction,
-  SyncOp,
-  WormholeAddress,
-  WormholeNetwork,
-} from "./Contract";
-import { ethers } from "ethers";
-import { ChainName } from "../chains";
-import { SetValidPeriod } from "../governance_payload";
-
-export class EvmPythUpgradable implements Contract<EvmPythUpgradableState> {
-  public type = ContractType.EvmPythUpgradable;
-  public networkId;
-  private address;
-
-  private contract: ethers.Contract;
-
-  constructor(
-    networkId: NetworkId,
-    address: string,
-    contract: ethers.Contract
-  ) {
-    this.networkId = networkId;
-    this.address = address;
-    this.contract = contract;
-  }
-
-  public getAddress() {
-    return this.address;
-  }
-
-  // TODO: these getters will need the full PythUpgradable ABI
-  public async getAuthority(): Promise<WormholeAddress> {
-    // FIXME: read from data sources
-    return {
-      emitter: "123454",
-      chainId: 1,
-      network: "mainnet",
-    };
-  }
-
-  // get the chainId that identifies this contract
-  public async getChain(): Promise<ChainName> {
-    // FIXME: read from data sources
-    return "polygon";
-  }
-
-  public async getState(): Promise<EvmPythUpgradableState> {
-    const bytecodeSha = ethers.utils.sha256(
-      (await this.contract.provider.getCode(this.contract.address)) as string
-    );
-    const validTimePeriod =
-      (await this.contract.getValidTimePeriod()) as bigint;
-    return {
-      bytecodeSha,
-      validTimePeriod: validTimePeriod.toString(),
-    };
-  }
-
-  public async sync(target: EvmPythUpgradableState): Promise<SyncOp[]> {
-    const myState = await this.getState();
-    const authority = await this.getAuthority();
-    const myChainId = await this.getChain();
-    const whInstructions = [];
-
-    if (myState.validTimePeriod !== target.validTimePeriod) {
-      whInstructions.push(
-        new SetValidPeriod(myChainId, BigInt(target.validTimePeriod))
-      );
-    }
-
-    return whInstructions.map(
-      (value) =>
-        new SendGovernanceInstruction(
-          value,
-          authority,
-          this.submitGovernanceVaa
-        )
-    );
-  }
-
-  public async submitGovernanceVaa(vaa: string): Promise<boolean> {
-    // FIXME: also needs the full PythUpgradable ABI
-    // await this.contract.executeGovernanceInstruction("0x" + vaa)
-    return true;
-  }
-}
-
-export interface EvmPythUpgradableState {
-  bytecodeSha: string;
-  // bigint serialized as a string
-  validTimePeriod: string;
-}

+ 0 - 43
governance/xc_admin/packages/xc_admin_common/src/contracts/EvmWormholeReceiver.ts

@@ -1,43 +0,0 @@
-import { ethers } from "ethers";
-import { Contract, ContractType, NetworkId, SyncOp } from "./Contract";
-
-export class EvmWormholeReceiver implements Contract<EvmWormholeReceiverState> {
-  public type = ContractType.EvmWormholeReceiver;
-  public networkId;
-  private address;
-
-  private contract: ethers.Contract;
-
-  constructor(
-    networkId: NetworkId,
-    address: string,
-    contract: ethers.Contract
-  ) {
-    this.networkId = networkId;
-    this.address = address;
-    this.contract = contract;
-  }
-
-  public getAddress() {
-    return this.address;
-  }
-
-  public async getState(): Promise<EvmWormholeReceiverState> {
-    const bytecodeSha = ethers.utils.sha256(
-      (await this.contract.provider.getCode(this.contract.address)) as string
-    );
-
-    return {
-      bytecodeSha,
-    };
-  }
-
-  public async sync(target: EvmWormholeReceiverState): Promise<SyncOp[]> {
-    // TODO
-    return [];
-  }
-}
-
-export interface EvmWormholeReceiverState {
-  bytecodeSha: string;
-}

+ 0 - 58
governance/xc_admin/packages/xc_admin_common/src/contracts/config.ts

@@ -1,58 +0,0 @@
-import { ethers } from "ethers";
-import PythAbi from "@pythnetwork/pyth-sdk-solidity/abis/IPyth.json";
-import { Contract, ContractType, NetworkId } from "./Contract";
-import { EvmPythUpgradable } from "./EvmPythUpgradable";
-import { EvmWormholeReceiver } from "./EvmWormholeReceiver";
-
-export function getEvmProvider(
-  networkId: NetworkId,
-  networksConfig: any
-): ethers.providers.Provider {
-  const networkConfig = networksConfig["evm"][networkId]!;
-  return ethers.getDefaultProvider(networkConfig.url);
-}
-
-export function loadContractConfig(
-  contractsConfig: any,
-  networksConfig: any
-): Contract<any>[] {
-  const contracts = [];
-  for (const contractConfig of contractsConfig) {
-    contracts.push(fromConfig(contractConfig, networksConfig));
-  }
-  return contracts;
-}
-
-function fromConfig(contractConfig: any, networksConfig: any): Contract<any> {
-  switch (contractConfig.type) {
-    case ContractType.EvmPythUpgradable: {
-      const ethersContract = new ethers.Contract(
-        contractConfig.address,
-        PythAbi,
-        getEvmProvider(contractConfig.networkId, networksConfig)
-      );
-
-      return new EvmPythUpgradable(
-        contractConfig.networkId,
-        contractConfig.address,
-        ethersContract
-      );
-    }
-    case ContractType.EvmWormholeReceiver: {
-      const ethersContract = new ethers.Contract(
-        contractConfig.address,
-        // TODO: pass in an appropriate ABI here
-        [],
-        getEvmProvider(contractConfig.networkId, networksConfig)
-      );
-
-      return new EvmWormholeReceiver(
-        contractConfig.networkId,
-        contractConfig.address,
-        ethersContract
-      );
-    }
-    default:
-      throw new Error(`unknown contract type: ${contractConfig.type}`);
-  }
-}

+ 0 - 4
governance/xc_admin/packages/xc_admin_common/src/contracts/index.ts

@@ -1,4 +0,0 @@
-export * from "./config";
-export * from "./Contract";
-export * from "./EvmPythUpgradable";
-export * from "./EvmWormholeReceiver";

+ 0 - 1
governance/xc_admin/packages/xc_admin_common/src/index.ts

@@ -9,6 +9,5 @@ export * from "./bpf_upgradable_loader";
 export * from "./deterministic_oracle_accounts";
 export * from "./cranks";
 export * from "./message_buffer";
-export * from "./contracts";
 export * from "./executor";
 export * from "./chains";

+ 0 - 2
governance/xc_admin/packages/xc_admin_frontend/Dockerfile

@@ -8,8 +8,6 @@ USER 1000
 
 COPY --chown=1000:1000 governance/xc_admin governance/xc_admin
 COPY --chown=1000:1000 pythnet/message_buffer pythnet/message_buffer
-COPY --chown=1000:1000 target_chains/ethereum/sdk/solidity target_chains/ethereum/sdk/solidity
-COPY --chown=1000:1000 governance/xc_admin/packages/xc_admin_common governance/xc_admin/packages/xc_admin_common
 
 ENV NODE_ENV production
 ENV NEXT_TELEMETRY_DISABLED 1