Explorar el Código

solana/scripts: shim tests

Evan Gray hace 7 meses
padre
commit
fafcd36849

+ 0 - 0
solana/scripts/initialize.ts → solana/scripts/initialize_testnet.ts


+ 70 - 0
solana/scripts/post_message_shim_test.ts

@@ -0,0 +1,70 @@
+import { deriveFeeCollectorKey } from "@certusone/wormhole-sdk/lib/cjs/solana/wormhole";
+import {
+  AnchorProvider,
+  Program,
+  setProvider,
+  Wallet,
+  web3,
+} from "@coral-xyz/anchor";
+import { bs58 } from "@coral-xyz/anchor/dist/cjs/utils/bytes";
+import { WormholePostMessageShim } from "../../svm/wormhole-core-shims/anchor/idls/wormhole_post_message_shim";
+import WormholePostMessageShimIdl from "../../svm/wormhole-core-shims/anchor/idls/wormhole_post_message_shim.json";
+
+// Usage:
+// RPC_URL="https://api.devnet.solana.com" CORE_BRIDGE_PROGRAM_ID=3u8hJUVTA4jH1wYAyUur7FFZVQ8H635K3tSHHF4ssjQ5 SOLANA_KEY="<full_path>.json" MSG="hello wormhole" npx tsx post_message.ts
+
+(async () => {
+  const RPC_URL = process.env.RPC_URL;
+  if (!RPC_URL) {
+    throw new Error("RPC_URL is required");
+  }
+
+  const CORE_BRIDGE_PROGRAM_ID = process.env.CORE_BRIDGE_PROGRAM_ID;
+  if (!CORE_BRIDGE_PROGRAM_ID) {
+    throw new Error("CORE_BRIDGE_PROGRAM_ID is required");
+  }
+
+  const coreBridgeAddress = new web3.PublicKey(CORE_BRIDGE_PROGRAM_ID);
+
+  const MSG = process.env.MSG;
+  if (!MSG) {
+    throw new Error("MSG is required");
+  }
+
+  const connection = new web3.Connection(RPC_URL, "confirmed");
+
+  const key = process.env.SOLANA_KEY;
+
+  if (!key) {
+    throw new Error("SOLANA_KEY is required");
+  }
+
+  const payer = web3.Keypair.fromSecretKey(
+    key.endsWith(".json") ? new Uint8Array(require(key)) : bs58.decode(key)
+  );
+  const provider = new AnchorProvider(connection, new Wallet(payer));
+  setProvider(provider);
+
+  const program = new Program<WormholePostMessageShim>(
+    WormholePostMessageShimIdl as WormholePostMessageShim
+  );
+
+  const tx = await program.methods
+    .postMessage(0, { confirmed: {} }, Buffer.from(MSG, "ascii"))
+    // there seems to be an extra "program" field that is not needed and is marked optional in `svm/wormhole-core-shims/tests/wormhole-post-message-shim.ts` using anchor 0.30.1
+    // @ts-ignore
+    .accounts({
+      emitter: payer.publicKey,
+      wormholeProgram: coreBridgeAddress,
+    })
+    .preInstructions([
+      // gotta pay the fee
+      web3.SystemProgram.transfer({
+        fromPubkey: payer.publicKey,
+        toPubkey: deriveFeeCollectorKey(coreBridgeAddress), // fee collector
+        lamports: 100, // hardcoded for tilt in devnet_setup.sh
+      }),
+    ])
+    .rpc();
+  console.log(tx);
+})();

+ 97 - 0
solana/scripts/verify_vaa_shim_test.ts

@@ -0,0 +1,97 @@
+import { keccak256 } from "@certusone/wormhole-sdk/lib/cjs/utils/keccak";
+import { parseVaa } from "@certusone/wormhole-sdk/lib/cjs/vaa";
+import {
+  AnchorProvider,
+  Program,
+  setProvider,
+  Wallet,
+  web3,
+} from "@coral-xyz/anchor";
+import { bs58 } from "@coral-xyz/anchor/dist/cjs/utils/bytes";
+import { WormholeVerifyVaaShim } from "../../svm/wormhole-core-shims/anchor/idls/wormhole_verify_vaa_shim";
+import WormholeVerifyVaaShimIdl from "../../svm/wormhole-core-shims/anchor/idls/wormhole_verify_vaa_shim.json";
+
+// Usage:
+// RPC_URL="https://api.devnet.solana.com" CORE_BRIDGE_PROGRAM_ID=3u8hJUVTA4jH1wYAyUur7FFZVQ8H635K3tSHHF4ssjQ5 SOLANA_KEY="<full_path>.json" VAA="<base64 VAA from wormholescan>" npx tsx post_message.ts
+
+const GUARDIAN_SET_SEED = "GuardianSet";
+
+(async () => {
+  const RPC_URL = process.env.RPC_URL;
+  if (!RPC_URL) {
+    throw new Error("RPC_URL is required");
+  }
+
+  const CORE_BRIDGE_PROGRAM_ID = process.env.CORE_BRIDGE_PROGRAM_ID;
+  if (!CORE_BRIDGE_PROGRAM_ID) {
+    throw new Error("CORE_BRIDGE_PROGRAM_ID is required");
+  }
+
+  const coreBridgeAddress = new web3.PublicKey(CORE_BRIDGE_PROGRAM_ID);
+
+  const VAA = process.env.VAA;
+  if (!VAA) {
+    throw new Error("VAA is required");
+  }
+
+  const connection = new web3.Connection(RPC_URL, "confirmed");
+
+  const key = process.env.SOLANA_KEY;
+
+  if (!key) {
+    throw new Error("SOLANA_KEY is required");
+  }
+
+  const payer = web3.Keypair.fromSecretKey(
+    key.endsWith(".json") ? new Uint8Array(require(key)) : bs58.decode(key)
+  );
+  const provider = new AnchorProvider(connection, new Wallet(payer));
+  setProvider(provider);
+
+  const program = new Program<WormholeVerifyVaaShim>(
+    WormholeVerifyVaaShimIdl as WormholeVerifyVaaShim
+  );
+  const signatureKeypair = web3.Keypair.generate();
+  console.log(`signature public key: ${signatureKeypair.publicKey.toString()}`);
+  const buf = Buffer.from(VAA, "base64");
+  const vaa = parseVaa(buf);
+  const tx = await program.methods
+    .postSignatures(
+      vaa.guardianSetIndex,
+      vaa.guardianSignatures.length,
+      vaa.guardianSignatures.map((s) => [s.index, ...s.signature])
+    )
+    .accounts({ guardianSignatures: signatureKeypair.publicKey })
+    .signers([signatureKeypair])
+    .rpc();
+  console.log(`verify tx1: ${tx}`);
+
+  // Convert guardian_set_index to big-endian bytes
+  const guardianSetIndex = vaa.guardianSetIndex;
+  const indexBuffer = Buffer.alloc(4); // guardian_set_index is a u32
+  indexBuffer.writeUInt32BE(guardianSetIndex);
+  const [guardianSet, guardianSetBump] = web3.PublicKey.findProgramAddressSync(
+    [Buffer.from(GUARDIAN_SET_SEED), indexBuffer],
+    coreBridgeAddress
+  );
+
+  const tx2 = await program.methods
+    .verifyHash(guardianSetBump, [...keccak256(vaa.hash)])
+    .accounts({
+      guardianSet,
+      guardianSignatures: signatureKeypair.publicKey,
+    })
+    .preInstructions([
+      web3.ComputeBudgetProgram.setComputeUnitLimit({
+        units: 420_000,
+      }),
+    ])
+    .postInstructions([
+      await program.methods
+        .closeSignatures()
+        .accounts({ guardianSignatures: signatureKeypair.publicKey })
+        .instruction(),
+    ])
+    .rpc();
+  console.log(`verify tx2: ${tx2}`);
+})();