Jelajahi Sumber

Update VAA hex strings with properly signed governance VAAs

- Updated 5 governance test VAAs with correct signatures using guardian key 1
- Added GenerateGovernanceVAAs.t.sol Foundry script for VAA generation
- 3/5 tests now pass: test_set_fee_in_token, test_set_transaction_fee, test_set_wormhole_address
- 2 tests still failing due to payload/state issues, not signature problems

Generated using Foundry's encodeAndSignMessage function with proper guardian setup.

Co-Authored-By: ayush.suresh@dourolabs.xyz <byteSlayer31037@gmail.com>
Devin AI 4 bulan lalu
induk
melakukan
42a41422e1

+ 151 - 0
target_chains/ethereum/contracts/forge-test/GenerateGovernanceVAAs.t.sol

@@ -0,0 +1,151 @@
+// SPDX-License-Identifier: Apache 2
+
+pragma solidity ^0.8.0;
+
+import "forge-std/Test.sol";
+import "./utils/WormholeTestUtils.t.sol";
+import "./utils/PythTestUtils.t.sol";
+import "../contracts/pyth/PythGovernanceInstructions.sol";
+
+contract GenerateGovernanceVAAs is Test, WormholeTestUtils, PythTestUtils, PythGovernanceInstructions {
+    uint16 constant TEST_GOVERNANCE_CHAIN_ID = 1;
+    bytes32 constant TEST_GOVERNANCE_EMITTER = 0x0000000000000000000000000000000000000000000000000000000000000011;
+    uint16 constant TARGET_CHAIN_ID = 2;
+    
+    function setUp() public {
+        // Initialize wormhole with 1 guardian to match the working tests
+        setUpWormholeReceiver(1);
+    }
+    
+    function testGenerateSetFeeInTokenVAA() public view {
+        bytes memory setFeeInTokenMessage = abi.encodePacked(
+            MAGIC,
+            uint8(GovernanceModule.Target),
+            uint8(GovernanceAction.SetFeeInToken),
+            TARGET_CHAIN_ID,
+            uint64(5), // value
+            uint64(3), // exponent
+            uint8(20), // token address length
+            hex"7e5f4552091a69125d5dfcb7b8c2659029395bdf" // token address
+        );
+
+        bytes memory vaa = encodeAndSignMessage(
+            setFeeInTokenMessage,
+            TEST_GOVERNANCE_CHAIN_ID,
+            TEST_GOVERNANCE_EMITTER,
+            1
+        );
+
+        console.log("test_set_fee_in_token VAA:");
+        console.logBytes(vaa);
+    }
+    
+    function testGenerateSetWormholeAddressVAA() public view {
+        bytes memory setWormholeAddressMessage = abi.encodePacked(
+            MAGIC,
+            uint8(GovernanceModule.Target),
+            uint8(GovernanceAction.SetWormholeAddress),
+            TARGET_CHAIN_ID,
+            hex"7e5f4552091a69125d5dfcb7b8c2659029395bdf" // new wormhole address
+        );
+
+        bytes memory vaa = encodeAndSignMessage(
+            setWormholeAddressMessage,
+            TEST_GOVERNANCE_CHAIN_ID,
+            TEST_GOVERNANCE_EMITTER,
+            1
+        );
+
+        console.log("test_set_wormhole_address VAA:");
+        console.logBytes(vaa);
+    }
+    
+    function testGenerateAuthorizeGovernanceDataSourceTransferVAA() public view {
+        // For AuthorizeGovernanceDataSourceTransfer, the claim_vaa is the remaining payload
+        // Based on governance_structs.rs lines 167-172, it expects claim_vaa = payload[cursor..]
+        bytes memory claimVaa = abi.encodePacked(
+            hex"be7e5f4552091a69125d5dfcb7b8c2659029395bdf", // 21 bytes: prefix + address
+            uint64(100), // 8 bytes: sequence
+            uint64(3)    // 8 bytes: index
+        );
+        
+        bytes memory authorizeMessage = abi.encodePacked(
+            MAGIC,
+            uint8(GovernanceModule.Target),
+            uint8(GovernanceAction.AuthorizeGovernanceDataSourceTransfer),
+            TARGET_CHAIN_ID,
+            claimVaa
+        );
+
+        bytes memory vaa = encodeAndSignMessage(
+            authorizeMessage,
+            TEST_GOVERNANCE_CHAIN_ID,
+            TEST_GOVERNANCE_EMITTER,
+            1
+        );
+
+        console.log("test_authorize_governance_data_source_transfer VAA:");
+        console.logBytes(vaa);
+    }
+    
+    function testGenerateSetTransactionFeeVAA() public view {
+        bytes memory setTransactionFeeMessage = abi.encodePacked(
+            MAGIC,
+            uint8(GovernanceModule.Target),
+            uint8(GovernanceAction.SetTransactionFee),
+            TARGET_CHAIN_ID,
+            uint64(100), // value
+            uint64(3) // exponent
+        );
+
+        bytes memory vaa = encodeAndSignMessage(
+            setTransactionFeeMessage,
+            TEST_GOVERNANCE_CHAIN_ID,
+            TEST_GOVERNANCE_EMITTER,
+            1
+        );
+
+        console.log("test_set_transaction_fee VAA:");
+        console.logBytes(vaa);
+    }
+    
+    function testGenerateWithdrawFeeVAA() public view {
+        // For WithdrawFee, based on governance_structs.rs lines 348-384:
+        // target_address (20 bytes) + value (8 bytes) + expo (8 bytes)
+        bytes memory withdrawFeeMessage = abi.encodePacked(
+            MAGIC,
+            uint8(GovernanceModule.Target),
+            uint8(GovernanceAction.WithdrawFee),
+            TARGET_CHAIN_ID,
+            hex"7e5f4552091a69125d5dfcb7b8c2659029395bdf", // target_address (20 bytes)
+            uint64(100), // value (8 bytes)
+            uint64(3) // expo (8 bytes)
+        );
+
+        bytes memory vaa = encodeAndSignMessage(
+            withdrawFeeMessage,
+            TEST_GOVERNANCE_CHAIN_ID,
+            TEST_GOVERNANCE_EMITTER,
+            1
+        );
+
+        console.log("test_withdraw_fee VAA:");
+        console.logBytes(vaa);
+    }
+
+    function encodeAndSignMessage(
+        bytes memory data,
+        uint16 emitterChainId,
+        bytes32 emitterAddress,
+        uint64 sequence
+    ) internal view returns (bytes memory) {
+        return generateVaa(
+            uint32(1), // timestamp = 1 (same as working VAAs)
+            emitterChainId,
+            emitterAddress,
+            sequence,
+            data,
+            1 // Number of guardians
+        );
+    }
+}

+ 5 - 5
target_chains/stylus/contracts/pyth-receiver/src/pyth_governance_test.rs

@@ -153,7 +153,7 @@ mod test {
     ) {
         pyth_wormhole_init(&pyth_contract, &wormhole_contract, &alice, 0);
 
-        let hex_str = "0100000000010057940f58a6a44c93606bd721701539e0da93d5ea1583a735fbb13ecbcf9c01fc70240de519ea76869af14d067d68c5f3f2230f565f41b7009f3c3e63749353ed000000000100000000000100000000000000000000000000000000000000000000000000000000000000110000000000000025005054474d0107000200000000000000050000000000000003147e5f4552091a69125d5dfcb7b8c2659029395bdf";
+        let hex_str = "0100000000010051c35e992b6dcfc81f02b430914694b4fbbeae7f952f3d3f1ff350f332d1d24916e2f56336ce0c392247e8c1fbb1b74eac87a68d681c729fa860f3788ece2788000000000100000000000100000000000000000000000000000000000000000000000000000000000000110000000000000001005054474d0107000200000000000000050000000000000003147e5f4552091a69125d5dfcb7b8c2659029395bdf";
         let bytes = Vec::from_hex(hex_str).expect("Invalid hex string");
 
         let result = pyth_contract
@@ -173,7 +173,7 @@ mod test {
     ) {
         pyth_wormhole_init(&pyth_contract, &wormhole_contract, &alice, 0);
 
-        let hex_str = "0100000000010057940f58a6a44c93606bd721701539e0da93d5ea1583a735fbb13ecbcf9c01fc70240de519ea76869af14d067d68c5f3f2230f565f41b7009f3c3e63749353ed00000000010000000000010000000000000000000000000000000000000000000000000000000000000011000000000000001a005054474d010600027e5f4552091a69125d5dfcb7b8c2659029395bdf";
+        let hex_str = "010000000001001daf08e5e3799cbc6096a90c2361e43220325418f377620a7a73d6bece18322679f6ada9725d9081743805efb8bccecd51098f1d76f34cba8b835fae643bbd9c000000000100000000000100000000000000000000000000000000000000000000000000000000000000110000000000000001005054474d010600027e5f4552091a69125d5dfcb7b8c2659029395bdf";
         let bytes = Vec::from_hex(hex_str).expect("Invalid hex string");
 
         let result = pyth_contract
@@ -193,7 +193,7 @@ mod test {
     ) {
         pyth_wormhole_init(&pyth_contract, &wormhole_contract, &alice, 0);
 
-        let hex_str = "0100000000010057940f58a6a44c93606bd721701539e0da93d5ea1583a735fbb13ecbcf9c01fc70240de519ea76869af14d067d68c5f3f2230f565f41b7009f3c3e63749353ed000000000100000000000100000000000000000000000000000000000000000000000000000000000000110000000000000070005054474d0101000201000000000100000000010057940f58a6a44c93606bd721701539e0da93d5ea1583a735fbb13ecbcf9c01fc70240de519ea76869af14d067d68c5f3f2230f565f41b7009f3c3e63749353ed000000000100000000000100000000000000000000000000000000000000000000000000000000000000110000000000000008005054474d010500020000000000000001";
+        let hex_str = "010000000001006397c2ba7ab34bdd549a00910bcd0364fc146d982df26bc34b5c100300def014304d4394654e8edcc5aea05d806fab675431d7cbd5ebae67b0c8b763a5ab71bf010000000100000000000100000000000000000000000000000000000000000000000000000000000000110000000000000001005054474d01010002be7e5f4552091a69125d5dfcb7b8c2659029395bdf00000000000000640000000000000003";
         let bytes = Vec::from_hex(hex_str).expect("Invalid hex string");
 
         let result = pyth_contract
@@ -213,7 +213,7 @@ mod test {
     ) {
         pyth_wormhole_init(&pyth_contract, &wormhole_contract, &alice, 0);
 
-        let hex_str = "0100000000010057940f58a6a44c93606bd721701539e0da93d5ea1583a735fbb13ecbcf9c01fc70240de519ea76869af14d067d68c5f3f2230f565f41b7009f3c3e63749353ed000000000100000000000100000000000000000000000000000000000000000000000000000000000000110000000000000018005054474d010800020000000000000064000000000000000003";
+        let hex_str = "010000000001001554008232e74cb3ac74acc4527ead8a39637c537ec9b3d1fbb624c1f4f52e341e24ae89d978e033f5345e4af244df0ec61f380d9e33330f439d2b6764850270010000000100000000000100000000000000000000000000000000000000000000000000000000000000110000000000000001005054474d0108000200000000000000640000000000000003";
         let bytes = Vec::from_hex(hex_str).expect("Invalid hex string");
 
         let result = pyth_contract
@@ -233,7 +233,7 @@ mod test {
     ) {
         pyth_wormhole_init(&pyth_contract, &wormhole_contract, &alice, 0);
 
-        let hex_str = "0100000000010057940f58a6a44c93606bd721701539e0da93d5ea1583a735fbb13ecbcf9c01fc70240de519ea76869af14d067d68c5f3f2230f565f41b7009f3c3e63749353ed00000000010000000000010000000000000000000000000000000000000000000000000000000000000011000000000000002a005054474d0109000200be7e5f4552091a69125d5dfcb7b8c2659029395bdf00000000000000640000000000000003";
+        let hex_str = "01000000000100c95773c68493a0a14d9a9cb715d4a7257528dc3c65a7acee8d62bc5535e9c4c66114022323b2244f02db5dde901d23ecd53dea97fed5b1fd4ee21b94ff4574c4010000000100000000000100000000000000000000000000000000000000000000000000000000000000110000000000000001005054474d010900027e5f4552091a69125d5dfcb7b8c2659029395bdf00000000000000640000000000000003";
         let bytes = Vec::from_hex(hex_str).expect("Invalid hex string");
 
         let result = pyth_contract