71
71
dashmap::DashMap,
72
72
itertools::Itertools,
73
73
log::*,
74
+ pythnet_sdk::pythnet,
74
75
rand::Rng,
75
76
rayon::{
76
77
iter::{IntoParallelIterator, IntoParallelRefIterator, ParallelIterator},
@@ -1295,6 +1296,9 @@ enum AccumulatorUpdateError {
1295
1296
1296
1297
#[error("io error")]
1297
1298
Io(#[from] std::io::Error),
1299
+
1300
+ #[error("could not parse Pubkey from environment")]
1301
+ InvalidEnvPubkey(#[from] solana_sdk::pubkey::ParsePubkeyError),
1298
1302
}
1299
1303
1300
1304
impl Bank {
@@ -2508,25 +2512,27 @@ impl Bank {
2508
2512
fn update_accumulator_impl(&self) -> std::result::Result<(), AccumulatorUpdateError> {
2509
2513
use {
2510
2514
byteorder::ReadBytesExt,
2511
- solana_pyth ::{
2515
+ pythnet_sdk ::{
2512
2516
accumulators::{merkle::MerkleAccumulator, Accumulator},
2513
- PYTH_PID,
2517
+ pythnet::PYTH_PID,
2518
+ MESSAGE_BUFFER_PID,
2514
2519
},
2515
2520
solana_sdk::borsh::BorshSerialize,
2516
2521
};
2517
2522
2518
2523
// Use the current Clock to determine the index into the accumulator ring buffer.
2519
2524
let ring_index = (self.clock().slot % 10_000) as u32;
2520
2525
2521
- // Find all accounts owned by the Accumulator program using get_program_accounts, and
2526
+ // Find all accounts owned by the Message Buffer program using get_program_accounts, and
2522
2527
// extract the account data.
2523
- //
2524
- // NOTE: This is set to the Syvar temporarily but will be changed to the Accumulator
2525
- // program once it is deployed with an official address.
2526
- let accumulator_program =
2527
- Pubkey::from_str("Vbmv1jt4vyuqBZcpYPpnVhrqVe5e6ZPb6JxDcffRHUM").unwrap();
2528
2528
2529
- let accounts = self.get_program_accounts(&accumulator_program, &ScanConfig::new(true))
2529
+ let message_buffer_pid = Self::env_pubkey_or(
2530
+ "MESSAGE_BUFFER_PID",
2531
+ Pubkey::new_from_array(MESSAGE_BUFFER_PID),
2532
+ )?;
2533
+
2534
+ let accounts = self
2535
+ .get_program_accounts(&message_buffer_pid, &ScanConfig::new(true))
2530
2536
.map_err(|_| AccumulatorUpdateError::GetProgramAccounts)?;
2531
2537
2532
2538
// Filter accounts that don't match the Anchor sighash.
@@ -2571,11 +2577,17 @@ impl Bank {
2571
2577
.sorted_unstable()
2572
2578
.dedup();
2573
2579
2580
+ let pyth_pid = Self::env_pubkey_or("PYTH_PID", Pubkey::new_from_array(pythnet::PYTH_PID))?;
2581
+
2574
2582
// We now generate a Proof PDA (Owned by the System Program) to store the resulting Proof
2575
2583
// Set. The derivation includes the ring buffer index to simulate a ring buffer in order
2576
2584
// for RPC users to select the correct proof for an associated VAA.
2577
2585
let (accumulator_account, _) = Pubkey::find_program_address(
2578
- &[b"AccumulatorState", &PYTH_PID, &ring_index.to_be_bytes()],
2586
+ &[
2587
+ b"AccumulatorState",
2588
+ &pyth_pid.as_ref(),
2589
+ &ring_index.to_be_bytes(),
2590
+ ],
2579
2591
&solana_sdk::system_program::id(),
2580
2592
);
2581
2593
@@ -2592,7 +2604,7 @@ impl Bank {
2592
2604
// Wormhole message generation code that would normally be called, but the Guardian
2593
2605
// set filters our messages so this does not pose a security risk.
2594
2606
if let Some(accumulator) = MerkleAccumulator::from_set(accounts) {
2595
- self.post_accumulator_attestation(accumulator)?;
2607
+ self.post_accumulator_attestation(accumulator, ring_index )?;
2596
2608
}
2597
2609
2598
2610
// Write the Account Set into `accumulator_state` so that the hermes application can
@@ -2605,25 +2617,30 @@ impl Bank {
2605
2617
/// TODO: Safe integer conversion checks if any are missed.
2606
2618
fn post_accumulator_attestation(
2607
2619
&self,
2608
- acc: solana_pyth::accumulators::merkle::MerkleAccumulator,
2620
+ acc: pythnet_sdk::accumulators::merkle::MerkleAccumulator,
2621
+ ring_index: u32,
2609
2622
) -> std::result::Result<(), AccumulatorUpdateError> {
2610
2623
use {
2611
- solana_pyth::{
2624
+ pythnet_sdk::{
2625
+ pythnet::{ACCUMULATOR_SEQUENCE_ADDR, WORMHOLE_PID},
2612
2626
wormhole::{AccumulatorSequenceTracker, MessageData, PostedMessageUnreliableData},
2613
- ACCUMULATOR_EMITTER_ADDR, ACCUMULATOR_SEQUENCE_ADDR, WORMHOLE_PID ,
2627
+ ACCUMULATOR_EMITTER_ADDRESS ,
2614
2628
},
2615
2629
solana_sdk::borsh::BorshSerialize,
2616
2630
};
2617
2631
2618
- // Calculate the offset into the Accumulator ring buffer.
2619
- let ring_index = (self.clock().slot % 10_000) as u32;
2632
+ let accumulator_sequence_addr = Self::env_pubkey_or(
2633
+ "ACCUMULATOR_SEQUENCE_ADDR",
2634
+ Pubkey::new_from_array(ACCUMULATOR_SEQUENCE_ADDR),
2635
+ )?;
2620
2636
2621
2637
// Wormhole uses a Sequence account that is incremented each time a message is posted. As
2622
2638
// we aren't calling Wormhole we need to bump this ourselves. If it doesn't exist, we just
2623
2639
// create it instead.
2624
2640
let mut sequence: AccumulatorSequenceTracker = {
2625
- let data = Pubkey::new_from_array(ACCUMULATOR_SEQUENCE_ADDR);
2626
- let data = self.get_account_with_fixed_root(&data).unwrap_or_default();
2641
+ let data = self
2642
+ .get_account_with_fixed_root(&accumulator_sequence_addr)
2643
+ .unwrap_or_default();
2627
2644
let data = data.data();
2628
2645
solana_sdk::borsh::try_from_slice_unchecked(data)
2629
2646
.unwrap_or(AccumulatorSequenceTracker { sequence: 0 })
@@ -2642,58 +2659,66 @@ impl Bank {
2642
2659
nonce: 0,
2643
2660
sequence: sequence.sequence,
2644
2661
emitter_chain: 26,
2645
- emitter_address: ACCUMULATOR_EMITTER_ADDR ,
2662
+ emitter_address: ACCUMULATOR_EMITTER_ADDRESS ,
2646
2663
payload: acc.serialize(ring_index),
2647
2664
},
2648
2665
};
2649
2666
2650
2667
info!("msg_data.message: {:?}", message.message);
2668
+ let wormhole_pid =
2669
+ Self::env_pubkey_or("WORMHOLE_PID", Pubkey::new_from_array(WORMHOLE_PID))?;
2651
2670
2652
2671
// Now we can bump and write the Sequence account.
2653
2672
sequence.sequence += 1;
2654
- let sequence = sequence.try_to_vec().map_err(|_| AccumulatorUpdateError::FailedSequenceSerialization)?;
2673
+ let sequence = sequence
2674
+ .try_to_vec()
2675
+ .map_err(|_| AccumulatorUpdateError::FailedSequenceSerialization)?;
2655
2676
let sequence_balance = self.get_minimum_balance_for_rent_exemption(sequence.len());
2656
2677
let sequence_account = {
2657
- let owner = &WORMHOLE_PID;
2658
- let mut account = AccountSharedData::new(
2659
- sequence_balance,
2660
- sequence.len(),
2661
- &Pubkey::new_from_array(*owner),
2662
- );
2678
+ let owner = &wormhole_pid;
2679
+ let mut account = AccountSharedData::new(sequence_balance, sequence.len(), owner);
2663
2680
account.set_data(sequence);
2664
2681
account
2665
2682
};
2666
2683
2667
2684
// Serialize into (and create if necesary) the message account.
2668
- let message = message.try_to_vec().map_err(|_| AccumulatorUpdateError::FailedMessageSerialization)?;
2685
+ let message = message
2686
+ .try_to_vec()
2687
+ .map_err(|_| AccumulatorUpdateError::FailedMessageSerialization)?;
2669
2688
let message_balance = self.get_minimum_balance_for_rent_exemption(message.len());
2670
2689
let message_account = {
2671
- let owner = &WORMHOLE_PID;
2672
- let mut account = AccountSharedData::new(
2673
- message_balance,
2674
- message.len(),
2675
- &Pubkey::new_from_array(*owner),
2676
- );
2690
+ let owner = &wormhole_pid;
2691
+ let mut account = AccountSharedData::new(message_balance, message.len(), owner);
2677
2692
account.set_data(message);
2678
2693
account
2679
2694
};
2680
2695
2681
- // The accumulator_message_pda is derived at: 9VKyMGaKKJLUMBA5Fnf3dFiWMqGQkM979b5PP3rp62ck
2696
+ // The message_pda derivation includes the ring buffer index to simulate a ring buffer in order
2697
+ // for RPC users to select the message for an associated VAA.
2682
2698
let (message_pda, _) = Pubkey::find_program_address(
2683
- &[b"AccumulatorMessage"],
2684
- &Pubkey::new_from_array(WORMHOLE_PID) ,
2699
+ &[b"AccumulatorMessage", &ring_index.to_be_bytes() ],
2700
+ &wormhole_pid ,
2685
2701
);
2686
2702
2687
- self.store_account_and_update_capitalization(
2688
- &Pubkey::new_from_array(ACCUMULATOR_SEQUENCE_ADDR),
2689
- &sequence_account,
2690
- );
2703
+ self.store_account_and_update_capitalization(&accumulator_sequence_addr, &sequence_account);
2691
2704
2692
2705
self.store_account_and_update_capitalization(&message_pda, &message_account);
2693
2706
2694
2707
Ok(())
2695
2708
}
2696
2709
2710
+ fn env_pubkey_or(
2711
+ var: &str,
2712
+ default: Pubkey,
2713
+ ) -> std::result::Result<Pubkey, AccumulatorUpdateError> {
2714
+ Ok(std::env::var(var)
2715
+ .as_deref()
2716
+ .map(Pubkey::from_str)
2717
+ .ok()
2718
+ .transpose()?
2719
+ .unwrap_or(default))
2720
+ }
2721
+
2697
2722
pub fn epoch_duration_in_years(&self, prev_epoch: Epoch) -> f64 {
2698
2723
// period: time that has passed as a fraction of a year, basically the length of
2699
2724
// an epoch as a fraction of a year
@@ -18439,31 +18464,4 @@ pub(crate) mod tests {
18439
18464
// also be reclaimed by rent collection.
18440
18465
assert!(bank.load_accounts_data_size_delta() <= -(data_size as i64));
18441
18466
}
18442
-
18443
- #[test]
18444
- fn test_pyth_pda_addresses() {
18445
- use solana_sdk::pyth::wormhole::WORMHOLE_PID;
18446
- // TODO: make this a const
18447
- let (accumulator_message_pda, _) =
18448
- Pubkey::find_program_address(&[b"AccumulatorMessage"], &WORMHOLE_PID);
18449
-
18450
- //TODO: make this a const
18451
- //seeds = ["emitter"], seeds::program = cpiProgramId
18452
- let (emitter_pda_key, _) =
18453
- Pubkey::find_program_address(&[b"emitter"], &sysvar::accumulator::id());
18454
- //TODO: make this a const
18455
- //seeds = ["Sequence", wormholeEmitter], seeds::program = wormholeProgram
18456
- let (sequence_pda_key, _) = Pubkey::find_program_address(
18457
- &[b"Sequence", &emitter_pda_key.to_bytes()],
18458
- &WORMHOLE_PID,
18459
- );
18460
-
18461
- println!(
18462
- r"
18463
- accumulator_message_pda: {accumulator_message_pda:?}
18464
- emitter_pda_key: {emitter_pda_key:?}
18465
- sequence_pda_key: {sequence_pda_key:?}
18466
- "
18467
- );
18468
- }
18469
18467
}
0 commit comments