Skip to content

Commit 28647f6

Browse files
committed
fixup! pyth: introduce pyth accumulator library
1 parent ac34081 commit 28647f6

File tree

3 files changed

+69
-71
lines changed

3 files changed

+69
-71
lines changed

Cargo.lock

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

runtime/src/bank.rs

Lines changed: 65 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ use {
7171
dashmap::DashMap,
7272
itertools::Itertools,
7373
log::*,
74+
pythnet_sdk::pythnet,
7475
rand::Rng,
7576
rayon::{
7677
iter::{IntoParallelIterator, IntoParallelRefIterator, ParallelIterator},
@@ -1295,6 +1296,9 @@ enum AccumulatorUpdateError {
12951296

12961297
#[error("io error")]
12971298
Io(#[from] std::io::Error),
1299+
1300+
#[error("could not parse Pubkey from environment")]
1301+
InvalidEnvPubkey(#[from] solana_sdk::pubkey::ParsePubkeyError),
12981302
}
12991303

13001304
impl Bank {
@@ -2508,25 +2512,27 @@ impl Bank {
25082512
fn update_accumulator_impl(&self) -> std::result::Result<(), AccumulatorUpdateError> {
25092513
use {
25102514
byteorder::ReadBytesExt,
2511-
solana_pyth::{
2515+
pythnet_sdk::{
25122516
accumulators::{merkle::MerkleAccumulator, Accumulator},
2513-
PYTH_PID,
2517+
pythnet::PYTH_PID,
2518+
MESSAGE_BUFFER_PID,
25142519
},
25152520
solana_sdk::borsh::BorshSerialize,
25162521
};
25172522

25182523
// Use the current Clock to determine the index into the accumulator ring buffer.
25192524
let ring_index = (self.clock().slot % 10_000) as u32;
25202525

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
25222527
// 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();
25282528

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))
25302536
.map_err(|_| AccumulatorUpdateError::GetProgramAccounts)?;
25312537

25322538
// Filter accounts that don't match the Anchor sighash.
@@ -2571,11 +2577,17 @@ impl Bank {
25712577
.sorted_unstable()
25722578
.dedup();
25732579

2580+
let pyth_pid = Self::env_pubkey_or("PYTH_PID", Pubkey::new_from_array(pythnet::PYTH_PID))?;
2581+
25742582
// We now generate a Proof PDA (Owned by the System Program) to store the resulting Proof
25752583
// Set. The derivation includes the ring buffer index to simulate a ring buffer in order
25762584
// for RPC users to select the correct proof for an associated VAA.
25772585
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+
],
25792591
&solana_sdk::system_program::id(),
25802592
);
25812593

@@ -2592,7 +2604,7 @@ impl Bank {
25922604
// Wormhole message generation code that would normally be called, but the Guardian
25932605
// set filters our messages so this does not pose a security risk.
25942606
if let Some(accumulator) = MerkleAccumulator::from_set(accounts) {
2595-
self.post_accumulator_attestation(accumulator)?;
2607+
self.post_accumulator_attestation(accumulator, ring_index)?;
25962608
}
25972609

25982610
// Write the Account Set into `accumulator_state` so that the hermes application can
@@ -2605,25 +2617,30 @@ impl Bank {
26052617
/// TODO: Safe integer conversion checks if any are missed.
26062618
fn post_accumulator_attestation(
26072619
&self,
2608-
acc: solana_pyth::accumulators::merkle::MerkleAccumulator,
2620+
acc: pythnet_sdk::accumulators::merkle::MerkleAccumulator,
2621+
ring_index: u32,
26092622
) -> std::result::Result<(), AccumulatorUpdateError> {
26102623
use {
2611-
solana_pyth::{
2624+
pythnet_sdk::{
2625+
pythnet::{ACCUMULATOR_SEQUENCE_ADDR, WORMHOLE_PID},
26122626
wormhole::{AccumulatorSequenceTracker, MessageData, PostedMessageUnreliableData},
2613-
ACCUMULATOR_EMITTER_ADDR, ACCUMULATOR_SEQUENCE_ADDR, WORMHOLE_PID,
2627+
ACCUMULATOR_EMITTER_ADDRESS,
26142628
},
26152629
solana_sdk::borsh::BorshSerialize,
26162630
};
26172631

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+
)?;
26202636

26212637
// Wormhole uses a Sequence account that is incremented each time a message is posted. As
26222638
// we aren't calling Wormhole we need to bump this ourselves. If it doesn't exist, we just
26232639
// create it instead.
26242640
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();
26272644
let data = data.data();
26282645
solana_sdk::borsh::try_from_slice_unchecked(data)
26292646
.unwrap_or(AccumulatorSequenceTracker { sequence: 0 })
@@ -2642,58 +2659,66 @@ impl Bank {
26422659
nonce: 0,
26432660
sequence: sequence.sequence,
26442661
emitter_chain: 26,
2645-
emitter_address: ACCUMULATOR_EMITTER_ADDR,
2662+
emitter_address: ACCUMULATOR_EMITTER_ADDRESS,
26462663
payload: acc.serialize(ring_index),
26472664
},
26482665
};
26492666

26502667
info!("msg_data.message: {:?}", message.message);
2668+
let wormhole_pid =
2669+
Self::env_pubkey_or("WORMHOLE_PID", Pubkey::new_from_array(WORMHOLE_PID))?;
26512670

26522671
// Now we can bump and write the Sequence account.
26532672
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)?;
26552676
let sequence_balance = self.get_minimum_balance_for_rent_exemption(sequence.len());
26562677
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);
26632680
account.set_data(sequence);
26642681
account
26652682
};
26662683

26672684
// 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)?;
26692688
let message_balance = self.get_minimum_balance_for_rent_exemption(message.len());
26702689
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);
26772692
account.set_data(message);
26782693
account
26792694
};
26802695

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.
26822698
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,
26852701
);
26862702

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);
26912704

26922705
self.store_account_and_update_capitalization(&message_pda, &message_account);
26932706

26942707
Ok(())
26952708
}
26962709

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+
26972722
pub fn epoch_duration_in_years(&self, prev_epoch: Epoch) -> f64 {
26982723
// period: time that has passed as a fraction of a year, basically the length of
26992724
// an epoch as a fraction of a year
@@ -18439,31 +18464,4 @@ pub(crate) mod tests {
1843918464
// also be reclaimed by rent collection.
1844018465
assert!(bank.load_accounts_data_size_delta() <= -(data_size as i64));
1844118466
}
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-
}
1846918467
}

sdk/program/src/sysvar/accumulator.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
use crate::sysvar::Sysvar;
4949
pub use {
5050
crate::{account_info::AccountInfo, program_error::ProgramError, slot_history::SlotHistory},
51-
solana_pyth::accumulators::merkle::MerkleAccumulator,
51+
pythnet_sdk::accumulators::merkle::MerkleAccumulator,
5252
};
5353

5454
crate::declare_sysvar_id!(

0 commit comments

Comments
 (0)