浏览代码

feat: encourage using random treasury id (#1465)

* Encourage random treasury id

* GO
guibescos 1 年之前
父节点
当前提交
56cbace282

+ 1 - 0
target_chains/solana/Cargo.lock

@@ -3073,6 +3073,7 @@ dependencies = [
  "program-simulator",
  "pyth-solana-receiver-sdk",
  "pythnet-sdk",
+ "rand 0.8.5",
  "serde_wormhole",
  "solana-program",
  "solana-sdk",

+ 4 - 11
target_chains/solana/cli/src/main.rs

@@ -17,8 +17,7 @@ use {
     },
     pyth_solana_receiver::sdk::{
         deserialize_accumulator_update_data,
-        get_treasury_address,
-        DEFAULT_TREASURY_ID,
+        get_random_treasury_id,
     },
     pyth_solana_receiver_sdk::config::DataSource,
     pythnet_sdk::wire::v1::MerklePriceUpdate,
@@ -194,16 +193,9 @@ fn main() -> Result<()> {
                     },
                 );
 
-            // We need to send some rent to the treasury account, otherwise it won't be able to accept incoming transfers
-            let pay_treasury_rent = system_instruction::transfer(
-                &payer.pubkey(),
-                &get_treasury_address(DEFAULT_TREASURY_ID),
-                Rent::default().minimum_balance(0),
-            );
-
             process_transaction(
                 &rpc_client,
-                vec![initialize_pyth_receiver_instruction, pay_treasury_rent],
+                vec![initialize_pyth_receiver_instruction],
                 &vec![&payer],
             )?;
         }
@@ -268,7 +260,7 @@ pub fn process_post_price_update_atomic(
         header.guardian_set_index,
         serde_wormhole::to_vec(&(header, body)).unwrap(),
         merkle_price_update.clone(),
-        DEFAULT_TREASURY_ID,
+        get_random_treasury_id(),
     );
 
     process_transaction(
@@ -463,6 +455,7 @@ pub fn process_write_encoded_vaa_and_post_price_update(
         encoded_vaa_keypair.pubkey(),
         price_update_keypair.pubkey(),
         merkle_price_update.clone(),
+        get_random_treasury_id(),
     );
 
     // 2nd transaction

+ 1 - 0
target_chains/solana/programs/pyth-solana-receiver/Cargo.toml

@@ -23,6 +23,7 @@ byteorder = "1.4.3"
 wormhole-core-bridge-solana = {workspace = true}
 wormhole-raw-vaas = {version = "0.1.3", features = ["ruint", "on-chain"], default-features = false }
 pyth-solana-receiver-sdk = { path = "../../pyth_solana_receiver_sdk"}
+rand = "0.8.5"
 
 [dev-dependencies]
 solana-sdk = { workspace = true }

+ 10 - 2
target_chains/solana/programs/pyth-solana-receiver/src/sdk.rs

@@ -22,6 +22,7 @@ use {
         MerklePriceUpdate,
         Proof,
     },
+    rand::Rng,
     solana_program::instruction::Instruction,
     wormhole_core_bridge_solana::state::GuardianSet,
 };
@@ -72,9 +73,10 @@ impl accounts::PostUpdate {
         write_authority: Pubkey,
         encoded_vaa: Pubkey,
         price_update_account: Pubkey,
+        treasury_id: u8,
     ) -> Self {
         let config = get_config_address();
-        let treasury = get_treasury_address(DEFAULT_TREASURY_ID);
+        let treasury = get_treasury_address(treasury_id);
         accounts::PostUpdate {
             payer,
             encoded_vaa,
@@ -128,12 +130,14 @@ impl instruction::PostUpdate {
         encoded_vaa: Pubkey,
         price_update_account: Pubkey,
         merkle_price_update: MerklePriceUpdate,
+        treasury_id: u8,
     ) -> Instruction {
         let post_update_accounts = accounts::PostUpdate::populate(
             payer,
             write_authority,
             encoded_vaa,
             price_update_account,
+            treasury_id,
         )
         .to_account_metas(None);
         Instruction {
@@ -142,7 +146,7 @@ impl instruction::PostUpdate {
             data:       instruction::PostUpdate {
                 params: PostUpdateParams {
                     merkle_price_update,
-                    treasury_id: DEFAULT_TREASURY_ID,
+                    treasury_id,
                 },
             }
             .data(),
@@ -320,3 +324,7 @@ pub fn deserialize_accumulator_update_data(
         Proof::WormholeMerkle { vaa, updates } => return Ok((vaa.as_ref().to_vec(), updates)),
     }
 }
+
+pub fn get_random_treasury_id() -> u8 {
+    rand::thread_rng().gen()
+}

+ 5 - 0
target_chains/solana/programs/pyth-solana-receiver/tests/test_post_updates.rs

@@ -14,6 +14,7 @@ use {
         },
         sdk::{
             deserialize_accumulator_update_data,
+            get_random_treasury_id,
             DEFAULT_TREASURY_ID,
         },
     },
@@ -69,6 +70,7 @@ async fn test_post_update() {
                 encoded_vaa_addresses[0],
                 price_update_keypair.pubkey(),
                 merkle_price_updates[0].clone(),
+                DEFAULT_TREASURY_ID,
             ),
             &vec![&poster, &price_update_keypair],
             None,
@@ -111,6 +113,7 @@ async fn test_post_update() {
                 encoded_vaa_addresses[0],
                 price_update_keypair.pubkey(),
                 merkle_price_updates[1].clone(),
+                DEFAULT_TREASURY_ID,
             ),
             &vec![&poster, &price_update_keypair],
             None,
@@ -207,6 +210,7 @@ async fn test_post_update_wrong_encoded_vaa_owner() {
                     Pubkey::new_unique(), // Random pubkey instead of the encoded VAA address
                     price_update_keypair.pubkey(),
                     merkle_price_updates[0].clone(),
+                    get_random_treasury_id()
                 ),
                 &vec![&poster, &price_update_keypair],
                 None,
@@ -247,6 +251,7 @@ async fn test_post_update_wrong_setup() {
                     encoded_vaa_addresses[0],
                     price_update_keypair.pubkey(),
                     merkle_price_updates[0].clone(),
+                    get_random_treasury_id()
                 ),
                 &vec![&poster, &price_update_keypair],
                 None,

+ 13 - 17
target_chains/solana/sdk/js/pyth_solana_receiver/src/PythSolanaReceiver.ts

@@ -16,10 +16,10 @@ import {
 import {
   DEFAULT_PUSH_ORACLE_PROGRAM_ID,
   DEFAULT_RECEIVER_PROGRAM_ID,
-  DEFAULT_TREASURY_ID,
   DEFAULT_WORMHOLE_PROGRAM_ID,
   getConfigPda,
   getGuardianSetPda,
+  getRandomTreasuryId,
   getTreasuryPda,
 } from "./address";
 import { PublicKey, Keypair } from "@solana/web3.js";
@@ -397,6 +397,8 @@ export class PythSolanaReceiver {
     const priceFeedIdToPriceUpdateAccount: Record<string, PublicKey> = {};
     const closeInstructions: InstructionWithEphemeralSigners[] = [];
 
+    const treasuryId = getRandomTreasuryId();
+
     for (const priceUpdateData of priceUpdateDataArray) {
       const accumulatorUpdateData = parseAccumulatorUpdateData(
         Buffer.from(priceUpdateData, "base64")
@@ -411,14 +413,11 @@ export class PythSolanaReceiver {
             .postUpdateAtomic({
               vaa: trimmedVaa,
               merklePriceUpdate: update,
-              treasuryId: DEFAULT_TREASURY_ID,
+              treasuryId,
             })
             .accounts({
               priceUpdateAccount: priceUpdateKeypair.publicKey,
-              treasury: getTreasuryPda(
-                DEFAULT_TREASURY_ID,
-                this.receiver.programId
-              ),
+              treasury: getTreasuryPda(treasuryId, this.receiver.programId),
               config: getConfigPda(this.receiver.programId),
               guardianSet: getGuardianSetPda(
                 guardianSetIndex,
@@ -536,6 +535,8 @@ export class PythSolanaReceiver {
     const priceFeedIdToPriceUpdateAccount: Record<string, PublicKey> = {};
     const closeInstructions: InstructionWithEphemeralSigners[] = [];
 
+    const treasuryId = getRandomTreasuryId();
+
     for (const priceUpdateData of priceUpdateDataArray) {
       const accumulatorUpdateData = parseAccumulatorUpdateData(
         Buffer.from(priceUpdateData, "base64")
@@ -555,15 +556,12 @@ export class PythSolanaReceiver {
           instruction: await this.receiver.methods
             .postUpdate({
               merklePriceUpdate: update,
-              treasuryId: DEFAULT_TREASURY_ID,
+              treasuryId,
             })
             .accounts({
               encodedVaa,
               priceUpdateAccount: priceUpdateKeypair.publicKey,
-              treasury: getTreasuryPda(
-                DEFAULT_TREASURY_ID,
-                this.receiver.programId
-              ),
+              treasury: getTreasuryPda(treasuryId, this.receiver.programId),
               config: getConfigPda(this.receiver.programId),
             })
             .instruction(),
@@ -610,6 +608,8 @@ export class PythSolanaReceiver {
     const priceFeedIdToPriceUpdateAccount: Record<string, PublicKey> = {};
     const closeInstructions: InstructionWithEphemeralSigners[] = [];
 
+    const treasuryId = getRandomTreasuryId();
+
     for (const priceUpdateData of priceUpdateDataArray) {
       const accumulatorUpdateData = parseAccumulatorUpdateData(
         Buffer.from(priceUpdateData, "base64")
@@ -625,13 +625,12 @@ export class PythSolanaReceiver {
 
       for (const update of accumulatorUpdateData.updates) {
         const feedId = parsePriceFeedMessage(update.message).feedId;
-
         postInstructions.push({
           instruction: await this.pushOracle.methods
             .updatePriceFeed(
               {
                 merklePriceUpdate: update,
-                treasuryId: DEFAULT_TREASURY_ID,
+                treasuryId,
               },
               shardId,
               Array.from(feedId)
@@ -643,10 +642,7 @@ export class PythSolanaReceiver {
                 shardId,
                 feedId
               ),
-              treasury: getTreasuryPda(
-                DEFAULT_TREASURY_ID,
-                this.receiver.programId
-              ),
+              treasury: getTreasuryPda(treasuryId, this.receiver.programId),
               config: getConfigPda(this.receiver.programId),
             })
             .instruction(),

+ 3 - 1
target_chains/solana/sdk/js/pyth_solana_receiver/src/address.ts

@@ -38,7 +38,9 @@ export const getGuardianSetPda = (
  * The Pyth Solana Receiver has one treasury account for each u8 `treasuryId`.
  * This is meant to avoid write-locks on the treasury account by load-balancing the writes across multiple accounts.
  */
-export const DEFAULT_TREASURY_ID = 0;
+export function getRandomTreasuryId() {
+  return Math.floor(Math.random() * 256);
+}
 
 /**
  * Returns the address of a treasury account from the Pyth Solana Receiver program.