diff --git a/pythnet/pythnet_sdk/src/test_utils/mod.rs b/pythnet/pythnet_sdk/src/test_utils/mod.rs index b2bd1c285..e180b87d0 100644 --- a/pythnet/pythnet_sdk/src/test_utils/mod.rs +++ b/pythnet/pythnet_sdk/src/test_utils/mod.rs @@ -31,7 +31,11 @@ use { }, serde_wormhole::RawMessage, wormhole_sdk::{ - vaa::digest, + vaa::{ + digest, + Body, + Header, + }, Address, Chain, Vaa, @@ -174,9 +178,18 @@ pub fn create_vaa_from_payload( emitter_chain: Chain, sequence: u64, ) -> Vaa> { - let digest = libsecp256k1Message::parse_slice(&digest(payload).unwrap().secp256k_hash).unwrap(); let guardians = create_dummy_guardians(); + let body: Body> = Body { + emitter_chain, + emitter_address, + sequence, + payload: >::from(payload.to_vec()), + ..Default::default() + }; + + let digest = libsecp256k1Message::parse_slice(&body.digest().unwrap().secp256k_hash).unwrap(); + let signatures: Vec<(Signature, RecoveryId)> = guardians[0..NUM_SIGNATURES] .iter() .map(|x| libsecp256k1::sign(&digest, &x)) @@ -195,15 +208,13 @@ pub fn create_vaa_from_payload( }) .collect(); - let vaa: Vaa> = Vaa { + + let header = Header { version: 1, - emitter_chain, - emitter_address, - sequence, - payload: >::from(payload.to_vec()), signatures: wormhole_signatures, ..Default::default() }; - vaa + + (header, body).into() } diff --git a/target_chains/solana/programs/pyth-solana-receiver/tests/test_initialize.rs b/target_chains/solana/programs/pyth-solana-receiver/tests/test_post_updates.rs similarity index 100% rename from target_chains/solana/programs/pyth-solana-receiver/tests/test_initialize.rs rename to target_chains/solana/programs/pyth-solana-receiver/tests/test_post_updates.rs diff --git a/target_chains/solana/programs/pyth-solana-receiver/tests/test_post_updates_atomic.rs b/target_chains/solana/programs/pyth-solana-receiver/tests/test_post_updates_atomic.rs new file mode 100644 index 000000000..eea97fea5 --- /dev/null +++ b/target_chains/solana/programs/pyth-solana-receiver/tests/test_post_updates_atomic.rs @@ -0,0 +1,117 @@ +use { + crate::common::{ + trim_vaa_signatures, + DEFAULT_GUARDIAN_SET_INDEX, + }, + common::{ + setup_pyth_receiver, + ProgramTestFixtures, + }, + pyth_solana_receiver::{ + instruction::PostUpdatesAtomic, + sdk::deserialize_accumulator_update_data, + state::price_update::{ + PriceUpdateV1, + VerificationLevel, + }, + }, + pythnet_sdk::{ + messages::Message, + test_utils::{ + create_accumulator_message, + create_dummy_price_feed_message, + }, + }, + solana_sdk::{ + signature::Keypair, + signer::Signer, + }, + wormhole_core_bridge_solana::ID as BRIDGE_ID, +}; + +mod common; + + +#[tokio::test] +async fn test_post_updates_atomic() { + let feed_1 = create_dummy_price_feed_message(100); + let feed_2 = create_dummy_price_feed_message(200); + let message = create_accumulator_message(&[feed_1, feed_2], &[feed_1, feed_2], false); + let (vaa, merkle_price_updates) = deserialize_accumulator_update_data(message).unwrap(); + + let vaa = trim_vaa_signatures(vaa, 5); + + let ProgramTestFixtures { + mut program_simulator, + encoded_vaa_addresses: _, + } = setup_pyth_receiver(vec![]).await; + + let poster = program_simulator.get_funded_keypair().await.unwrap(); + let price_update_keypair = Keypair::new(); + + // post one update atomically + program_simulator + .process_ix( + PostUpdatesAtomic::populate( + poster.pubkey(), + price_update_keypair.pubkey(), + BRIDGE_ID, + DEFAULT_GUARDIAN_SET_INDEX, + vaa.clone(), + merkle_price_updates[0].clone(), + ), + &vec![&poster, &price_update_keypair], + None, + ) + .await + .unwrap(); + + + let mut price_update_account = program_simulator + .get_anchor_account_data::(price_update_keypair.pubkey()) + .await + .unwrap(); + + assert_eq!(price_update_account.write_authority, poster.pubkey()); + assert_eq!( + price_update_account.verification_level, + VerificationLevel::Partial(5) + ); + assert_eq!( + Message::PriceFeedMessage(price_update_account.price_message), + feed_1 + ); + + // post another update to the same account + program_simulator + .process_ix( + PostUpdatesAtomic::populate( + poster.pubkey(), + price_update_keypair.pubkey(), + BRIDGE_ID, + DEFAULT_GUARDIAN_SET_INDEX, + vaa.clone(), + merkle_price_updates[1].clone(), + ), + &vec![&poster, &price_update_keypair], + None, + ) + .await + .unwrap(); + + + price_update_account = program_simulator + .get_anchor_account_data::(price_update_keypair.pubkey()) + .await + .unwrap(); + + assert_eq!(price_update_account.write_authority, poster.pubkey()); + assert_eq!( + price_update_account.verification_level, + VerificationLevel::Partial(5) + ); + assert_eq!( + Message::PriceFeedMessage(price_update_account.price_message), + feed_2 + ); +}