Skip to content

Commit 044a867

Browse files
authored
Add verify command for wormhole msg (#363)
1 parent 1c17499 commit 044a867

File tree

3 files changed

+132
-7
lines changed

3 files changed

+132
-7
lines changed

third_party/pyth/multisig-wh-message-builder/package-lock.json

Lines changed: 13 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

third_party/pyth/multisig-wh-message-builder/package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,10 @@
4444
"@project-serum/anchor": "^0.25.0",
4545
"@solana/web3.js": "^1.53.0",
4646
"@sqds/mesh": "^1.0.6",
47+
"@types/lodash": "^4.14.186",
4748
"bs58": "^5.0.0",
4849
"commander": "^9.4.0",
49-
"ethers": "^5.7.0"
50+
"ethers": "^5.7.0",
51+
"lodash": "^4.17.21"
5052
}
5153
}

third_party/pyth/multisig-wh-message-builder/src/index.ts

Lines changed: 116 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,13 @@ import {
1515
TransactionInstruction,
1616
} from "@solana/web3.js";
1717
import Squads from "@sqds/mesh";
18-
import { getIxAuthorityPDA } from "@sqds/mesh";
18+
import { getIxAuthorityPDA, getIxPDA } from "@sqds/mesh";
19+
import { InstructionAccount } from "@sqds/mesh/lib/types";
1920
import bs58 from "bs58";
2021
import { program } from "commander";
2122
import * as fs from "fs";
2223
import { LedgerNodeWallet } from "./wallet";
24+
import loadash from "lodash";
2325

2426
setDefaultWasm("node");
2527

@@ -86,6 +88,44 @@ program
8688
);
8789
});
8890

91+
program
92+
.command("verify")
93+
.description("Verify given wormhole transaction has the given payload")
94+
.option("-c, --cluster <network>", "solana cluster to use", "devnet")
95+
.option("-l, --ledger", "use ledger")
96+
.option(
97+
"-lda, --ledger-derivation-account <number>",
98+
"ledger derivation account to use"
99+
)
100+
.option(
101+
"-ldc, --ledger-derivation-change <number>",
102+
"ledger derivation change to use"
103+
)
104+
.option(
105+
"-w, --wallet <filepath>",
106+
"multisig wallet secret key filepath",
107+
"keys/key.json"
108+
)
109+
.requiredOption("-p, --payload <hex-string>", "expected payload")
110+
.requiredOption("-t, --tx-pda <address>", "transaction PDA")
111+
.action(async (options) => {
112+
const cluster: Cluster = options.cluster;
113+
const squad = await getSquadsClient(
114+
cluster,
115+
options.ledger,
116+
options.ledgerDerivationAccount,
117+
options.ledgerDerivationChange,
118+
options.wallet
119+
);
120+
await verifyWormholePayload(
121+
options.cluster,
122+
squad,
123+
CONFIG[cluster].vault,
124+
new PublicKey(options.txPda),
125+
options.payload,
126+
);
127+
});
128+
89129
program
90130
.command("set-is-active")
91131
.description(
@@ -392,8 +432,7 @@ async function addInstructionsToTx(
392432
await squad.approveTransaction(txKey);
393433
console.log("Transaction approved.");
394434
console.log(
395-
`Tx URL: https://mesh${
396-
cluster === "devnet" ? "-devnet" : ""
435+
`Tx URL: https://mesh${cluster === "devnet" ? "-devnet" : ""
397436
}.squads.so/transactions/${vault.toBase58()}/tx/${txKey.toBase58()}`
398437
);
399438
}
@@ -531,6 +570,79 @@ async function createWormholeMsgMultisigTx(
531570
);
532571
}
533572

573+
async function verifyWormholePayload(
574+
cluster: Cluster,
575+
squad: Squads,
576+
vault: PublicKey,
577+
txPubkey: PublicKey,
578+
payload: string,
579+
) {
580+
const msAccount = await squad.getMultisig(vault);
581+
const emitter = squad.getAuthorityPDA(
582+
msAccount.publicKey,
583+
msAccount.authorityIndex
584+
);
585+
console.log(`Emitter Address: ${emitter.toBase58()}`);
586+
587+
const tx = await squad.getTransaction(txPubkey);
588+
589+
if (tx.instructionIndex !== 2) {
590+
throw new Error(`Expected 2 instructions in the transaction, found ${tx.instructionIndex + 1}`)
591+
}
592+
593+
const [ix1PubKey,] = getIxPDA(txPubkey, new anchor.BN(1), squad.multisigProgramId);
594+
const [ix2PubKey,] = getIxPDA(txPubkey, new anchor.BN(2), squad.multisigProgramId);
595+
596+
const onChainInstructions = await squad.getInstructions([ix1PubKey, ix2PubKey]);
597+
598+
console.log(onChainInstructions[0]);
599+
console.log(onChainInstructions[1]);
600+
601+
const [messagePDA,] = getIxAuthorityPDA(
602+
txPubkey,
603+
new anchor.BN(1),
604+
squad.multisigProgramId
605+
);
606+
607+
const wormholeIxs = await getWormholeMessageIx(
608+
cluster,
609+
emitter,
610+
emitter,
611+
messagePDA,
612+
squad.connection,
613+
payload
614+
);
615+
616+
console.log("Checking equality of the 1st instruction...");
617+
verifyOnChainInstruction(wormholeIxs[0], onChainInstructions[0] as InstructionAccount);
618+
619+
console.log("Checking equality of the 2nd instruction...");
620+
verifyOnChainInstruction(wormholeIxs[1], onChainInstructions[1] as InstructionAccount);
621+
622+
console.log("✅ The transaction is verified to be created with the given payload.");
623+
}
624+
625+
function verifyOnChainInstruction(instruction: TransactionInstruction, onChainInstruction: InstructionAccount) {
626+
if (!instruction.programId.equals(onChainInstruction.programId)) {
627+
throw new Error(
628+
`Program id mismatch: Expected ${instruction.programId.toBase58()}, found ${onChainInstruction.programId.toBase58()}`
629+
);
630+
}
631+
632+
if (!loadash.isEqual(instruction.keys, onChainInstruction.keys)) {
633+
throw new Error(
634+
`Instruction accounts mismatch. Expected ${instruction.keys}, found ${onChainInstruction.keys}`
635+
);
636+
}
637+
638+
const onChainData = onChainInstruction.data as Buffer;
639+
if (!instruction.data.equals(onChainData)) {
640+
throw new Error(
641+
`Instruction data mismatch. Expected ${instruction.data.toString('hex')}, Found ${onChainData.toString('hex')}`
642+
)
643+
}
644+
}
645+
534646
async function executeMultisigTx(
535647
cluster: string,
536648
squad: Squads,
@@ -584,8 +696,7 @@ async function executeMultisigTx(
584696
const signature = await provider.sendAndConfirm(executeTx);
585697

586698
console.log(
587-
`Executed tx: https://explorer.solana.com/tx/${signature}${
588-
cluster === "devnet" ? "?cluster=devnet" : ""
699+
`Executed tx: https://explorer.solana.com/tx/${signature}${cluster === "devnet" ? "?cluster=devnet" : ""
589700
}`
590701
);
591702

0 commit comments

Comments
 (0)