From d752778b261a18bbdb96f643f88287ebb2647ec3 Mon Sep 17 00:00:00 2001 From: Guillermo Bescos Date: Fri, 11 Oct 2024 19:00:10 +0100 Subject: [PATCH 1/2] feat: make deactivate stake take in vote accounts --- .../packages/xc_admin_cli/src/index.ts | 33 ++++++++++------- .../SolanaStakingMultisigInstruction.ts | 36 ++++++++++++++++++- .../src/multisig_transaction/index.ts | 5 ++- 3 files changed, 59 insertions(+), 15 deletions(-) diff --git a/governance/xc_admin/packages/xc_admin_cli/src/index.ts b/governance/xc_admin/packages/xc_admin_cli/src/index.ts index c21f22f250..67a48a5019 100644 --- a/governance/xc_admin/packages/xc_admin_cli/src/index.ts +++ b/governance/xc_admin/packages/xc_admin_cli/src/index.ts @@ -41,6 +41,7 @@ import { PROGRAM_AUTHORITY_ESCROW, createDetermisticPriceStoreInitializePublisherInstruction, createPriceStoreInstruction, + fetchStakeAccounts, findDetermisticStakeAccountAddress, getMultisigCluster, getProposalInstructions, @@ -59,6 +60,7 @@ import { DEFAULT_PRIORITY_FEE_CONFIG, TransactionBuilder, } from "@pythnetwork/solana-utils"; +import { bs58 } from "@coral-xyz/anchor/dist/cjs/utils/bytes"; export async function loadHotWalletOrLedger( wallet: string, @@ -389,8 +391,8 @@ multisigCommand( "Deactivate the delegated stake from the account" ) .requiredOption( - "-s, --stake-accounts ", - "stake accounts to be deactivated" + "-d, --vote-pubkeys ", + "vote account unstake from" ) .action(async (options: any) => { const vault = await loadVaultFromOptions(options); @@ -399,20 +401,25 @@ multisigCommand( cluster ); - const stakeAccounts = options.stakeAccounts - ? options.stakeAccounts.split(",").map((m: string) => new PublicKey(m)) + const voteAccounts: PublicKey[] = options.votePubkeys + ? options.votePubkeys.split(",").map((m: string) => new PublicKey(m)) : []; - const instructions = stakeAccounts.reduce( - (instructions: TransactionInstruction[], stakeAccount: PublicKey) => { - const transaction = StakeProgram.deactivate({ - stakePubkey: stakeAccount, - authorizedPubkey, - }); + const stakeAccounts = ( + await Promise.all( + voteAccounts.map((voteAccount: PublicKey) => + fetchStakeAccounts( + new Connection(getPythClusterApiUrl(cluster)), + voteAccount + ) + ) + ) + ).flat(); - return instructions.concat(transaction.instructions); - }, - [] + const instructions = stakeAccounts.flatMap( + (stakeAccount) => + StakeProgram.deactivate({ stakePubkey: stakeAccount, authorizedPubkey }) + .instructions ); await vault.proposeInstructions( diff --git a/governance/xc_admin/packages/xc_admin_common/src/multisig_transaction/SolanaStakingMultisigInstruction.ts b/governance/xc_admin/packages/xc_admin_common/src/multisig_transaction/SolanaStakingMultisigInstruction.ts index 835aae79b4..345512f5ad 100644 --- a/governance/xc_admin/packages/xc_admin_common/src/multisig_transaction/SolanaStakingMultisigInstruction.ts +++ b/governance/xc_admin/packages/xc_admin_common/src/multisig_transaction/SolanaStakingMultisigInstruction.ts @@ -1,4 +1,9 @@ -import { TransactionInstruction } from "@solana/web3.js"; +import { + Connection, + PublicKey, + StakeProgram, + TransactionInstruction, +} from "@solana/web3.js"; import { MultisigInstruction, MultisigInstructionProgram, @@ -6,6 +11,7 @@ import { } from "."; import { AnchorAccounts } from "./anchor"; import { StakeInstruction } from "@solana/web3.js"; +import { bs58 } from "@coral-xyz/anchor/dist/cjs/utils/bytes"; export class SolanaStakingMultisigInstruction implements MultisigInstruction { readonly program = MultisigInstructionProgram.SolanaStakingProgram; @@ -115,3 +121,31 @@ export class SolanaStakingMultisigInstruction implements MultisigInstruction { } } } + +export async function fetchStakeAccounts( + connection: Connection, + voterAccount: PublicKey +) { + const stakeAccounts = await connection.getProgramAccounts( + StakeProgram.programId, + { + encoding: "base64", + filters: [ + { + memcmp: { + offset: 0, + bytes: bs58.encode(Buffer.from([2, 0, 0, 0])), + }, + }, + { + memcmp: { + offset: 124, + bytes: voterAccount.toBase58(), + }, + }, + ], + } + ); + + return stakeAccounts.map((account) => account.pubkey); +} diff --git a/governance/xc_admin/packages/xc_admin_common/src/multisig_transaction/index.ts b/governance/xc_admin/packages/xc_admin_common/src/multisig_transaction/index.ts index a8c86c8e8c..e449684d79 100644 --- a/governance/xc_admin/packages/xc_admin_common/src/multisig_transaction/index.ts +++ b/governance/xc_admin/packages/xc_admin_common/src/multisig_transaction/index.ts @@ -173,4 +173,7 @@ export { PythMultisigInstruction } from "./PythMultisigInstruction"; export { AnchorMultisigInstruction } from "./MessageBufferMultisigInstruction"; export { SystemProgramMultisigInstruction } from "./SystemProgramInstruction"; export { BpfUpgradableLoaderInstruction } from "./BpfUpgradableLoaderMultisigInstruction"; -export { SolanaStakingMultisigInstruction } from "./SolanaStakingMultisigInstruction"; +export { + SolanaStakingMultisigInstruction, + fetchStakeAccounts, +} from "./SolanaStakingMultisigInstruction"; From 7b49019f94b4c55e980482301f3f264ae4bf1df2 Mon Sep 17 00:00:00 2001 From: Guillermo Bescos Date: Wed, 16 Oct 2024 13:50:17 +0100 Subject: [PATCH 2/2] fix node version --- .github/workflows/ci-ethereum-contract.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/ci-ethereum-contract.yml b/.github/workflows/ci-ethereum-contract.yml index 9c1c7ed93a..ff8b69902d 100644 --- a/.github/workflows/ci-ethereum-contract.yml +++ b/.github/workflows/ci-ethereum-contract.yml @@ -21,6 +21,9 @@ jobs: working-directory: target_chains/ethereum/contracts/ steps: - uses: actions/checkout@v3 + - uses: actions/setup-node@v4 + with: + node-version-file: "package.json" - uses: pnpm/action-setup@v4 name: Install pnpm