Skip to content

Commit 56cbace

Browse files
authored
feat: encourage using random treasury id (#1465)
* Encourage random treasury id * GO
1 parent ba435ba commit 56cbace

File tree

7 files changed

+37
-31
lines changed

7 files changed

+37
-31
lines changed

target_chains/solana/Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

target_chains/solana/cli/src/main.rs

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@ use {
1717
},
1818
pyth_solana_receiver::sdk::{
1919
deserialize_accumulator_update_data,
20-
get_treasury_address,
21-
DEFAULT_TREASURY_ID,
20+
get_random_treasury_id,
2221
},
2322
pyth_solana_receiver_sdk::config::DataSource,
2423
pythnet_sdk::wire::v1::MerklePriceUpdate,
@@ -194,16 +193,9 @@ fn main() -> Result<()> {
194193
},
195194
);
196195

197-
// We need to send some rent to the treasury account, otherwise it won't be able to accept incoming transfers
198-
let pay_treasury_rent = system_instruction::transfer(
199-
&payer.pubkey(),
200-
&get_treasury_address(DEFAULT_TREASURY_ID),
201-
Rent::default().minimum_balance(0),
202-
);
203-
204196
process_transaction(
205197
&rpc_client,
206-
vec![initialize_pyth_receiver_instruction, pay_treasury_rent],
198+
vec![initialize_pyth_receiver_instruction],
207199
&vec![&payer],
208200
)?;
209201
}
@@ -268,7 +260,7 @@ pub fn process_post_price_update_atomic(
268260
header.guardian_set_index,
269261
serde_wormhole::to_vec(&(header, body)).unwrap(),
270262
merkle_price_update.clone(),
271-
DEFAULT_TREASURY_ID,
263+
get_random_treasury_id(),
272264
);
273265

274266
process_transaction(
@@ -463,6 +455,7 @@ pub fn process_write_encoded_vaa_and_post_price_update(
463455
encoded_vaa_keypair.pubkey(),
464456
price_update_keypair.pubkey(),
465457
merkle_price_update.clone(),
458+
get_random_treasury_id(),
466459
);
467460

468461
// 2nd transaction

target_chains/solana/programs/pyth-solana-receiver/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ byteorder = "1.4.3"
2323
wormhole-core-bridge-solana = {workspace = true}
2424
wormhole-raw-vaas = {version = "0.1.3", features = ["ruint", "on-chain"], default-features = false }
2525
pyth-solana-receiver-sdk = { path = "../../pyth_solana_receiver_sdk"}
26+
rand = "0.8.5"
2627

2728
[dev-dependencies]
2829
solana-sdk = { workspace = true }

target_chains/solana/programs/pyth-solana-receiver/src/sdk.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use {
2222
MerklePriceUpdate,
2323
Proof,
2424
},
25+
rand::Rng,
2526
solana_program::instruction::Instruction,
2627
wormhole_core_bridge_solana::state::GuardianSet,
2728
};
@@ -72,9 +73,10 @@ impl accounts::PostUpdate {
7273
write_authority: Pubkey,
7374
encoded_vaa: Pubkey,
7475
price_update_account: Pubkey,
76+
treasury_id: u8,
7577
) -> Self {
7678
let config = get_config_address();
77-
let treasury = get_treasury_address(DEFAULT_TREASURY_ID);
79+
let treasury = get_treasury_address(treasury_id);
7880
accounts::PostUpdate {
7981
payer,
8082
encoded_vaa,
@@ -128,12 +130,14 @@ impl instruction::PostUpdate {
128130
encoded_vaa: Pubkey,
129131
price_update_account: Pubkey,
130132
merkle_price_update: MerklePriceUpdate,
133+
treasury_id: u8,
131134
) -> Instruction {
132135
let post_update_accounts = accounts::PostUpdate::populate(
133136
payer,
134137
write_authority,
135138
encoded_vaa,
136139
price_update_account,
140+
treasury_id,
137141
)
138142
.to_account_metas(None);
139143
Instruction {
@@ -142,7 +146,7 @@ impl instruction::PostUpdate {
142146
data: instruction::PostUpdate {
143147
params: PostUpdateParams {
144148
merkle_price_update,
145-
treasury_id: DEFAULT_TREASURY_ID,
149+
treasury_id,
146150
},
147151
}
148152
.data(),
@@ -320,3 +324,7 @@ pub fn deserialize_accumulator_update_data(
320324
Proof::WormholeMerkle { vaa, updates } => return Ok((vaa.as_ref().to_vec(), updates)),
321325
}
322326
}
327+
328+
pub fn get_random_treasury_id() -> u8 {
329+
rand::thread_rng().gen()
330+
}

target_chains/solana/programs/pyth-solana-receiver/tests/test_post_updates.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use {
1414
},
1515
sdk::{
1616
deserialize_accumulator_update_data,
17+
get_random_treasury_id,
1718
DEFAULT_TREASURY_ID,
1819
},
1920
},
@@ -69,6 +70,7 @@ async fn test_post_update() {
6970
encoded_vaa_addresses[0],
7071
price_update_keypair.pubkey(),
7172
merkle_price_updates[0].clone(),
73+
DEFAULT_TREASURY_ID,
7274
),
7375
&vec![&poster, &price_update_keypair],
7476
None,
@@ -111,6 +113,7 @@ async fn test_post_update() {
111113
encoded_vaa_addresses[0],
112114
price_update_keypair.pubkey(),
113115
merkle_price_updates[1].clone(),
116+
DEFAULT_TREASURY_ID,
114117
),
115118
&vec![&poster, &price_update_keypair],
116119
None,
@@ -207,6 +210,7 @@ async fn test_post_update_wrong_encoded_vaa_owner() {
207210
Pubkey::new_unique(), // Random pubkey instead of the encoded VAA address
208211
price_update_keypair.pubkey(),
209212
merkle_price_updates[0].clone(),
213+
get_random_treasury_id()
210214
),
211215
&vec![&poster, &price_update_keypair],
212216
None,
@@ -247,6 +251,7 @@ async fn test_post_update_wrong_setup() {
247251
encoded_vaa_addresses[0],
248252
price_update_keypair.pubkey(),
249253
merkle_price_updates[0].clone(),
254+
get_random_treasury_id()
250255
),
251256
&vec![&poster, &price_update_keypair],
252257
None,

target_chains/solana/sdk/js/pyth_solana_receiver/src/PythSolanaReceiver.ts

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@ import {
1616
import {
1717
DEFAULT_PUSH_ORACLE_PROGRAM_ID,
1818
DEFAULT_RECEIVER_PROGRAM_ID,
19-
DEFAULT_TREASURY_ID,
2019
DEFAULT_WORMHOLE_PROGRAM_ID,
2120
getConfigPda,
2221
getGuardianSetPda,
22+
getRandomTreasuryId,
2323
getTreasuryPda,
2424
} from "./address";
2525
import { PublicKey, Keypair } from "@solana/web3.js";
@@ -397,6 +397,8 @@ export class PythSolanaReceiver {
397397
const priceFeedIdToPriceUpdateAccount: Record<string, PublicKey> = {};
398398
const closeInstructions: InstructionWithEphemeralSigners[] = [];
399399

400+
const treasuryId = getRandomTreasuryId();
401+
400402
for (const priceUpdateData of priceUpdateDataArray) {
401403
const accumulatorUpdateData = parseAccumulatorUpdateData(
402404
Buffer.from(priceUpdateData, "base64")
@@ -411,14 +413,11 @@ export class PythSolanaReceiver {
411413
.postUpdateAtomic({
412414
vaa: trimmedVaa,
413415
merklePriceUpdate: update,
414-
treasuryId: DEFAULT_TREASURY_ID,
416+
treasuryId,
415417
})
416418
.accounts({
417419
priceUpdateAccount: priceUpdateKeypair.publicKey,
418-
treasury: getTreasuryPda(
419-
DEFAULT_TREASURY_ID,
420-
this.receiver.programId
421-
),
420+
treasury: getTreasuryPda(treasuryId, this.receiver.programId),
422421
config: getConfigPda(this.receiver.programId),
423422
guardianSet: getGuardianSetPda(
424423
guardianSetIndex,
@@ -536,6 +535,8 @@ export class PythSolanaReceiver {
536535
const priceFeedIdToPriceUpdateAccount: Record<string, PublicKey> = {};
537536
const closeInstructions: InstructionWithEphemeralSigners[] = [];
538537

538+
const treasuryId = getRandomTreasuryId();
539+
539540
for (const priceUpdateData of priceUpdateDataArray) {
540541
const accumulatorUpdateData = parseAccumulatorUpdateData(
541542
Buffer.from(priceUpdateData, "base64")
@@ -555,15 +556,12 @@ export class PythSolanaReceiver {
555556
instruction: await this.receiver.methods
556557
.postUpdate({
557558
merklePriceUpdate: update,
558-
treasuryId: DEFAULT_TREASURY_ID,
559+
treasuryId,
559560
})
560561
.accounts({
561562
encodedVaa,
562563
priceUpdateAccount: priceUpdateKeypair.publicKey,
563-
treasury: getTreasuryPda(
564-
DEFAULT_TREASURY_ID,
565-
this.receiver.programId
566-
),
564+
treasury: getTreasuryPda(treasuryId, this.receiver.programId),
567565
config: getConfigPda(this.receiver.programId),
568566
})
569567
.instruction(),
@@ -610,6 +608,8 @@ export class PythSolanaReceiver {
610608
const priceFeedIdToPriceUpdateAccount: Record<string, PublicKey> = {};
611609
const closeInstructions: InstructionWithEphemeralSigners[] = [];
612610

611+
const treasuryId = getRandomTreasuryId();
612+
613613
for (const priceUpdateData of priceUpdateDataArray) {
614614
const accumulatorUpdateData = parseAccumulatorUpdateData(
615615
Buffer.from(priceUpdateData, "base64")
@@ -625,13 +625,12 @@ export class PythSolanaReceiver {
625625

626626
for (const update of accumulatorUpdateData.updates) {
627627
const feedId = parsePriceFeedMessage(update.message).feedId;
628-
629628
postInstructions.push({
630629
instruction: await this.pushOracle.methods
631630
.updatePriceFeed(
632631
{
633632
merklePriceUpdate: update,
634-
treasuryId: DEFAULT_TREASURY_ID,
633+
treasuryId,
635634
},
636635
shardId,
637636
Array.from(feedId)
@@ -643,10 +642,7 @@ export class PythSolanaReceiver {
643642
shardId,
644643
feedId
645644
),
646-
treasury: getTreasuryPda(
647-
DEFAULT_TREASURY_ID,
648-
this.receiver.programId
649-
),
645+
treasury: getTreasuryPda(treasuryId, this.receiver.programId),
650646
config: getConfigPda(this.receiver.programId),
651647
})
652648
.instruction(),

target_chains/solana/sdk/js/pyth_solana_receiver/src/address.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,9 @@ export const getGuardianSetPda = (
3838
* The Pyth Solana Receiver has one treasury account for each u8 `treasuryId`.
3939
* This is meant to avoid write-locks on the treasury account by load-balancing the writes across multiple accounts.
4040
*/
41-
export const DEFAULT_TREASURY_ID = 0;
41+
export function getRandomTreasuryId() {
42+
return Math.floor(Math.random() * 256);
43+
}
4244

4345
/**
4446
* Returns the address of a treasury account from the Pyth Solana Receiver program.

0 commit comments

Comments
 (0)