[solana] Add wrong vaa tests (#1262)

* Checkpoint

* Checkpoint

* Cleanup

* Checkpoint, debug

* Go

* Checkpoint

* Fix

* Add new error and test

* Cleanup

* Add another test

* Keep adding errors

* Another test

* Add comment

* Rename

* Rename
This commit is contained in:
guibescos 2024-01-31 14:16:43 +00:00 committed by GitHub
parent 4edef3a4ed
commit 2ab72d994d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 498 additions and 43 deletions

View File

@ -2981,6 +2981,7 @@ dependencies = [
name = "program-simulator"
version = "0.1.0"
dependencies = [
"anchor-lang",
"bincode",
"borsh 0.10.3",
"solana-client",

View File

@ -15,3 +15,4 @@ solana-program-test = "1.16.20"
solana-program = "1.16.20"
bincode = "1.3.3"
borsh = "0.10.3"
anchor-lang = "0.28.0"

View File

@ -2,8 +2,12 @@ use {
borsh::BorshDeserialize,
solana_program::{
hash::Hash,
instruction::Instruction,
instruction::{
Instruction,
InstructionError,
},
native_token::LAMPORTS_PER_SOL,
program_error::ProgramError,
pubkey::Pubkey,
system_instruction,
},
@ -14,11 +18,15 @@ use {
ProgramTestBanksClientExt,
},
solana_sdk::{
compute_budget,
signature::{
Keypair,
Signer,
},
transaction::Transaction,
transaction::{
Transaction,
TransactionError,
},
},
};
@ -43,15 +51,19 @@ impl ProgramSimulator {
/// Process a transaction containing `instruction` signed by `signers`.
/// `payer` is used to pay for and sign the transaction.
pub async fn process_ix(
pub async fn process_ix_with_default_compute_limit(
&mut self,
instruction: Instruction,
signers: &Vec<&Keypair>,
payer: Option<&Keypair>,
) -> Result<(), BanksClientError> {
let compute_units_ixs =
compute_budget::ComputeBudgetInstruction::set_compute_unit_limit(2000000);
let actual_payer = payer.unwrap_or(&self.genesis_keypair);
let mut transaction =
Transaction::new_with_payer(&[instruction], Some(&actual_payer.pubkey()));
let mut transaction = Transaction::new_with_payer(
&[instruction, compute_units_ixs],
Some(&actual_payer.pubkey()),
);
let blockhash = self
.banks_client
@ -71,7 +83,8 @@ impl ProgramSimulator {
let instruction =
system_instruction::transfer(&self.genesis_keypair.pubkey(), to, lamports);
self.process_ix(instruction, &vec![], None).await
self.process_ix_with_default_compute_limit(instruction, &vec![], None)
.await
}
pub async fn get_funded_keypair(&mut self) -> Result<Keypair, BanksClientError> {
@ -94,3 +107,10 @@ impl ProgramSimulator {
Ok(T::deserialize(&mut &account.data[8..])?)
}
}
pub fn into_transaction_error<T: Into<anchor_lang::prelude::Error>>(error: T) -> TransactionError {
TransactionError::InstructionError(
0,
InstructionError::try_from(u64::from(ProgramError::from(error.into()))).unwrap(),
)
}

View File

@ -2,16 +2,9 @@ use anchor_lang::prelude::*;
#[error_code]
pub enum ReceiverError {
// Pyth payload errors
#[msg("The tuple emitter chain, emitter doesn't match one of the valid data sources.")]
InvalidDataSource,
#[msg("The posted VAA account has the wrong owner.")]
WrongVaaOwner,
#[msg("The posted VAA has wrong magic number.")]
PostedVaaHeaderWrongMagicNumber,
#[msg("An error occurred when deserializing the VAA.")]
DeserializeVaaFailed,
#[msg("An error occurred when deserializing the updates.")]
DeserializeUpdateFailed,
#[msg("An error occurred when deserializing the message")]
DeserializeMessageFailed,
#[msg("Received an invalid wormhole message")]
@ -20,27 +13,39 @@ pub enum ReceiverError {
InvalidPriceUpdate,
#[msg("This type of message is not supported currently")]
UnsupportedMessageType,
#[msg("The signer is not authorized to perform this governance action")]
GovernanceAuthorityMismatch,
#[msg("The signer is not authorized to accept the governance authority")]
TargetGovernanceAuthorityMismatch,
#[msg("The governance authority needs to request a transfer first")]
NonexistentGovernanceAuthorityTransferRequest,
#[msg("Funds are insufficient to pay the receiving fee")]
InsufficientFunds,
// Wormhole contract encoded vaa error (from post_updates)
#[msg("The posted VAA account has the wrong owner.")]
WrongVaaOwner,
// Wormhole signatures verification errors (from post_updates_atomic)
#[msg("An error occurred when deserializing the VAA.")]
DeserializeVaaFailed,
#[msg("The number of guardian signatures is below the minimum")]
InsufficientGuardianSignatures,
#[msg("The Guardian Set account doesn't match the PDA derivation")]
InvalidGuardianSetPda,
// Wormhole errors
#[msg("Invalid VAA version")]
InvalidVaaVersion,
#[msg("Guardian set version in the VAA doesn't match the guardian set passed")]
GuardianSetMismatch,
#[msg("Guardian signature indices must be increasing")]
InvalidGuardianOrder,
#[msg("Guardian index exceeds the number of guardians in the set")]
InvalidGuardianIndex,
#[msg("A VAA signature is invalid")]
InvalidSignature,
#[msg("The recovered guardian public key doesn't match the guardian set")]
InvalidGuardianKeyRecovery,
#[msg("The guardian set account is owned by the wrong program")]
WrongGuardianSetOwner,
#[msg("The Guardian Set account doesn't match the PDA derivation")]
InvalidGuardianSetPda,
#[msg("The Guardian Set is expired")]
GuardianSetExpired,
// Governance errors
#[msg("The signer is not authorized to perform this governance action")]
GovernanceAuthorityMismatch,
#[msg("The signer is not authorized to accept the governance authority")]
TargetGovernanceAuthorityMismatch,
#[msg("The governance authority needs to request a transfer first")]
NonexistentGovernanceAuthorityTransferRequest,
}

View File

@ -143,7 +143,7 @@ pub mod pyth_solana_receiver {
// We do not allow for non-increasing guardian signature indices.
let index = usize::from(sig.guardian_index());
if let Some(last_index) = last_guardian_index {
require!(index > last_index, ReceiverError::InvalidGuardianIndex);
require!(index > last_index, ReceiverError::InvalidGuardianOrder);
}
// Does this guardian index exist in this guardian set?
@ -258,7 +258,7 @@ pub struct AuthorizeGovernanceAuthorityTransfer<'info> {
pub struct PostUpdates<'info> {
#[account(mut)]
pub payer: Signer<'info>,
#[account(owner = config.wormhole)]
#[account(owner = config.wormhole @ ReceiverError::WrongVaaOwner)]
/// CHECK: We aren't deserializing the VAA here but later with VaaAccount::load, which is the recommended way
pub encoded_vaa: AccountInfo<'info>,
#[account(seeds = [CONFIG_SEED.as_ref()], bump)]
@ -281,7 +281,7 @@ pub struct PostUpdatesAtomic<'info> {
/// CHECK: We can't use AccountVariant::<GuardianSet> here because its owner is hardcoded as the "official" Wormhole program and we want to get the wormhole address from the config.
/// Instead we do the same steps in deserialize_guardian_set_checked.
#[account(
owner = config.wormhole)]
owner = config.wormhole @ ReceiverError::WrongGuardianSetOwner)]
pub guardian_set: AccountInfo<'info>,
#[account(seeds = [CONFIG_SEED.as_ref()], bump)]
pub config: Account<'info, Config>,
@ -324,6 +324,12 @@ fn deserialize_guardian_set_checked(
ReceiverError::InvalidGuardianSetPda
);
let timestamp = Clock::get().map(Into::into)?;
require!(
guardian_set.inner().is_active(&timestamp),
ReceiverError::GuardianSetExpired
);
Ok(guardian_set)
}

View File

@ -44,6 +44,7 @@ use {
};
pub const DEFAULT_GUARDIAN_SET_INDEX: u32 = 0;
pub const WRONG_GUARDIAN_SET_INDEX: u32 = 1;
pub fn default_receiver_config() -> Config {
Config {
@ -65,11 +66,20 @@ pub struct ProgramTestFixtures {
pub encoded_vaa_addresses: Vec<Pubkey>,
}
pub fn build_encoded_vaa_account_from_vaa(vaa: Vaa<&RawMessage>) -> Account {
pub fn build_encoded_vaa_account_from_vaa(
vaa: Vaa<&RawMessage>,
wrong_setup_option: WrongSetupOption,
) -> Account {
let encoded_vaa_data = (
<EncodedVaa as anchor_lang::Discriminator>::DISCRIMINATOR,
Header {
status: ProcessingStatus::Verified,
status: {
if matches!(wrong_setup_option, WrongSetupOption::UnverifiedEncodedVaa) {
ProcessingStatus::Writing
} else {
ProcessingStatus::Verified
}
},
write_authority: Pubkey::new_unique(),
version: 1,
},
@ -87,9 +97,15 @@ pub fn build_encoded_vaa_account_from_vaa(vaa: Vaa<&RawMessage>) -> Account {
}
}
pub fn build_guardian_set_account() -> Account {
pub fn build_guardian_set_account(wrong_setup_option: WrongSetupOption) -> Account {
let guardian_set = GuardianSet {
index: DEFAULT_GUARDIAN_SET_INDEX,
index: {
if matches!(wrong_setup_option, WrongSetupOption::GuardianSetWrongIndex) {
WRONG_GUARDIAN_SET_INDEX
} else {
DEFAULT_GUARDIAN_SET_INDEX
}
},
keys: dummy_guardians()
.iter()
.map(|x| {
@ -101,7 +117,14 @@ pub fn build_guardian_set_account() -> Account {
})
.collect::<Vec<[u8; 20]>>(),
creation_time: 0.into(),
expiration_time: 0.into(),
expiration_time: {
if matches!(wrong_setup_option, WrongSetupOption::GuardianSetExpired) {
1
} else {
0
}
}
.into(),
};
let guardian_set_data = (
@ -119,12 +142,24 @@ pub fn build_guardian_set_account() -> Account {
rent_epoch: 0,
}
}
#[derive(Copy, Clone)]
pub enum WrongSetupOption {
None,
GuardianSetExpired,
GuardianSetWrongIndex,
UnverifiedEncodedVaa,
}
/**
* Setup to test the Pyth Receiver. The return values are a tuple composed of :
* - The program simulator, which is used to send transactions
* - The pubkeys of the encoded VAA accounts corresponding to the VAAs passed as argument, these accounts are prepopulated and can be used to test post_updates
*/
pub async fn setup_pyth_receiver(vaas: Vec<Vaa<&RawMessage>>) -> ProgramTestFixtures {
pub async fn setup_pyth_receiver(
vaas: Vec<Vaa<&RawMessage>>,
wrong_setup_option: WrongSetupOption,
) -> ProgramTestFixtures {
let mut program_test = ProgramTest::default();
program_test.add_program("pyth_solana_receiver", ID, None);
@ -132,11 +167,14 @@ pub async fn setup_pyth_receiver(vaas: Vec<Vaa<&RawMessage>>) -> ProgramTestFixt
for vaa in vaas {
let encoded_vaa_address = Pubkey::new_unique();
encoded_vaa_addresses.push(encoded_vaa_address);
program_test.add_account(encoded_vaa_address, build_encoded_vaa_account_from_vaa(vaa));
program_test.add_account(
encoded_vaa_address,
build_encoded_vaa_account_from_vaa(vaa, wrong_setup_option),
);
}
program_test.add_account(
get_guardian_set_address(BRIDGE_ID, DEFAULT_GUARDIAN_SET_INDEX),
build_guardian_set_account(),
build_guardian_set_account(wrong_setup_option),
);
let mut program_simulator = ProgramSimulator::start_from_program_test(program_test).await;
@ -145,7 +183,7 @@ pub async fn setup_pyth_receiver(vaas: Vec<Vaa<&RawMessage>>) -> ProgramTestFixt
let setup_keypair: Keypair = program_simulator.get_funded_keypair().await.unwrap();
program_simulator
.process_ix(
.process_ix_with_default_compute_limit(
Initialize::populate(&setup_keypair.pubkey(), initial_config.clone()),
&vec![&setup_keypair],
None,

View File

@ -1,9 +1,12 @@
use {
crate::common::WrongSetupOption,
common::{
setup_pyth_receiver,
ProgramTestFixtures,
},
program_simulator::into_transaction_error,
pyth_solana_receiver::{
error::ReceiverError,
instruction::PostUpdates,
sdk::deserialize_accumulator_update_data,
state::price_update::{
@ -18,6 +21,7 @@ use {
create_dummy_price_feed_message,
},
},
solana_program::pubkey::Pubkey,
solana_sdk::{
signature::Keypair,
signer::Signer,
@ -38,14 +42,18 @@ async fn test_post_updates() {
let ProgramTestFixtures {
mut program_simulator,
encoded_vaa_addresses,
} = setup_pyth_receiver(vec![serde_wormhole::from_slice(&vaa).unwrap()]).await;
} = setup_pyth_receiver(
vec![serde_wormhole::from_slice(&vaa).unwrap()],
WrongSetupOption::None,
)
.await;
let poster = program_simulator.get_funded_keypair().await.unwrap();
let price_update_keypair = Keypair::new();
// post one update
program_simulator
.process_ix(
.process_ix_with_default_compute_limit(
PostUpdates::populate(
poster.pubkey(),
encoded_vaa_addresses[0],
@ -76,7 +84,7 @@ async fn test_post_updates() {
// post another update to the same account
program_simulator
.process_ix(
.process_ix_with_default_compute_limit(
PostUpdates::populate(
poster.pubkey(),
encoded_vaa_addresses[0],
@ -105,3 +113,79 @@ async fn test_post_updates() {
feed_2
);
}
#[tokio::test]
async fn test_post_updates_wrong_encoded_vaa_owner() {
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 ProgramTestFixtures {
mut program_simulator,
encoded_vaa_addresses: _,
} = setup_pyth_receiver(
vec![serde_wormhole::from_slice(&vaa).unwrap()],
WrongSetupOption::None,
)
.await;
let poster = program_simulator.get_funded_keypair().await.unwrap();
let price_update_keypair = Keypair::new();
assert_eq!(
program_simulator
.process_ix_with_default_compute_limit(
PostUpdates::populate(
poster.pubkey(),
Pubkey::new_unique(), // Random pubkey instead of the encoded VAA address
price_update_keypair.pubkey(),
merkle_price_updates[0].clone(),
),
&vec![&poster, &price_update_keypair],
None,
)
.await
.unwrap_err()
.unwrap(),
into_transaction_error(ReceiverError::WrongVaaOwner)
);
}
#[tokio::test]
async fn test_post_updates_wrong_setup() {
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 ProgramTestFixtures {
mut program_simulator,
encoded_vaa_addresses,
} = setup_pyth_receiver(
vec![serde_wormhole::from_slice(&vaa).unwrap()],
WrongSetupOption::UnverifiedEncodedVaa,
)
.await;
let poster = program_simulator.get_funded_keypair().await.unwrap();
let price_update_keypair = Keypair::new();
assert_eq!(
program_simulator
.process_ix_with_default_compute_limit(
PostUpdates::populate(
poster.pubkey(),
encoded_vaa_addresses[0],
price_update_keypair.pubkey(),
merkle_price_updates[0].clone(),
),
&vec![&poster, &price_update_keypair],
None,
)
.await
.unwrap_err()
.unwrap(),
into_transaction_error(wormhole_core_bridge_solana::error::CoreBridgeError::UnverifiedVaa)
);
}

View File

@ -1,12 +1,20 @@
use {
crate::common::DEFAULT_GUARDIAN_SET_INDEX,
crate::common::{
WrongSetupOption,
DEFAULT_GUARDIAN_SET_INDEX,
},
common::{
setup_pyth_receiver,
ProgramTestFixtures,
},
program_simulator::into_transaction_error,
pyth_solana_receiver::{
error::ReceiverError,
instruction::PostUpdatesAtomic,
sdk::deserialize_accumulator_update_data,
sdk::{
deserialize_accumulator_update_data,
get_guardian_set_address,
},
state::price_update::{
PriceUpdateV1,
VerificationLevel,
@ -20,11 +28,13 @@ use {
trim_vaa_signatures,
},
},
serde_wormhole::RawMessage,
solana_sdk::{
signature::Keypair,
signer::Signer,
},
wormhole_core_bridge_solana::ID as BRIDGE_ID,
wormhole_sdk::Vaa,
};
mod common;
@ -45,14 +55,14 @@ async fn test_post_updates_atomic() {
let ProgramTestFixtures {
mut program_simulator,
encoded_vaa_addresses: _,
} = setup_pyth_receiver(vec![]).await;
} = setup_pyth_receiver(vec![], WrongSetupOption::None).await;
let poster = program_simulator.get_funded_keypair().await.unwrap();
let price_update_keypair = Keypair::new();
// post one update atomically
program_simulator
.process_ix(
.process_ix_with_default_compute_limit(
PostUpdatesAtomic::populate(
poster.pubkey(),
price_update_keypair.pubkey(),
@ -85,7 +95,7 @@ async fn test_post_updates_atomic() {
// post another update to the same account
program_simulator
.process_ix(
.process_ix_with_default_compute_limit(
PostUpdatesAtomic::populate(
poster.pubkey(),
price_update_keypair.pubkey(),
@ -116,3 +126,293 @@ async fn test_post_updates_atomic() {
feed_2
);
}
#[tokio::test]
async fn test_post_updates_atomic_wrong_vaa() {
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 ProgramTestFixtures {
mut program_simulator,
encoded_vaa_addresses: _,
} = setup_pyth_receiver(vec![], WrongSetupOption::None).await;
let poster = program_simulator.get_funded_keypair().await.unwrap();
let price_update_keypair = Keypair::new();
let mut vaa_buffer_copy: Vec<u8> = vaa.clone();
// Mess up with the length of signatures
vaa_buffer_copy[5] = 255;
assert_eq!(
program_simulator
.process_ix_with_default_compute_limit(
PostUpdatesAtomic::populate(
poster.pubkey(),
price_update_keypair.pubkey(),
BRIDGE_ID,
DEFAULT_GUARDIAN_SET_INDEX,
vaa_buffer_copy,
merkle_price_updates[0].clone(),
),
&vec![&poster, &price_update_keypair],
None,
)
.await
.unwrap_err()
.unwrap(),
into_transaction_error(ReceiverError::DeserializeVaaFailed)
);
let vaa_wrong_num_signatures = serde_wormhole::to_vec(&trim_vaa_signatures(
serde_wormhole::from_slice(&vaa).unwrap(),
4,
))
.unwrap();
assert_eq!(
program_simulator
.process_ix_with_default_compute_limit(
PostUpdatesAtomic::populate(
poster.pubkey(),
price_update_keypair.pubkey(),
BRIDGE_ID,
DEFAULT_GUARDIAN_SET_INDEX,
vaa_wrong_num_signatures.clone(),
merkle_price_updates[0].clone(),
),
&vec![&poster, &price_update_keypair],
None,
)
.await
.unwrap_err()
.unwrap(),
into_transaction_error(ReceiverError::InsufficientGuardianSignatures)
);
let mut vaa_copy: Vaa<&RawMessage> = serde_wormhole::from_slice(&vaa).unwrap();
vaa_copy.version = 0;
assert_eq!(
program_simulator
.process_ix_with_default_compute_limit(
PostUpdatesAtomic::populate(
poster.pubkey(),
price_update_keypair.pubkey(),
BRIDGE_ID,
DEFAULT_GUARDIAN_SET_INDEX,
serde_wormhole::to_vec(&vaa_copy).unwrap(),
merkle_price_updates[0].clone(),
),
&vec![&poster, &price_update_keypair],
None,
)
.await
.unwrap_err()
.unwrap(),
into_transaction_error(ReceiverError::InvalidVaaVersion)
);
let mut vaa_copy: Vaa<&RawMessage> = serde_wormhole::from_slice(&vaa).unwrap();
vaa_copy.guardian_set_index = 1;
assert_eq!(
program_simulator
.process_ix_with_default_compute_limit(
PostUpdatesAtomic::populate(
poster.pubkey(),
price_update_keypair.pubkey(),
BRIDGE_ID,
DEFAULT_GUARDIAN_SET_INDEX,
serde_wormhole::to_vec(&vaa_copy).unwrap(),
merkle_price_updates[0].clone(),
),
&vec![&poster, &price_update_keypair],
None,
)
.await
.unwrap_err()
.unwrap(),
into_transaction_error(ReceiverError::GuardianSetMismatch)
);
let mut vaa_copy: Vaa<&RawMessage> = serde_wormhole::from_slice(&vaa).unwrap();
vaa_copy.signatures[0] = vaa_copy.signatures[1];
assert_eq!(
program_simulator
.process_ix_with_default_compute_limit(
PostUpdatesAtomic::populate(
poster.pubkey(),
price_update_keypair.pubkey(),
BRIDGE_ID,
DEFAULT_GUARDIAN_SET_INDEX,
serde_wormhole::to_vec(&vaa_copy).unwrap(),
merkle_price_updates[0].clone(),
),
&vec![&poster, &price_update_keypair],
None,
)
.await
.unwrap_err()
.unwrap(),
into_transaction_error(ReceiverError::InvalidGuardianOrder)
);
let mut vaa_copy: Vaa<&RawMessage> = serde_wormhole::from_slice(&vaa).unwrap();
vaa_copy.signatures[0].index = 20;
assert_eq!(
program_simulator
.process_ix_with_default_compute_limit(
PostUpdatesAtomic::populate(
poster.pubkey(),
price_update_keypair.pubkey(),
BRIDGE_ID,
DEFAULT_GUARDIAN_SET_INDEX,
serde_wormhole::to_vec(&vaa_copy).unwrap(),
merkle_price_updates[0].clone(),
),
&vec![&poster, &price_update_keypair],
None,
)
.await
.unwrap_err()
.unwrap(),
into_transaction_error(ReceiverError::InvalidGuardianIndex)
);
let mut vaa_copy: Vaa<&RawMessage> = serde_wormhole::from_slice(&vaa).unwrap();
vaa_copy.signatures[0].signature[64] = 5;
assert_eq!(
program_simulator
.process_ix_with_default_compute_limit(
PostUpdatesAtomic::populate(
poster.pubkey(),
price_update_keypair.pubkey(),
BRIDGE_ID,
DEFAULT_GUARDIAN_SET_INDEX,
serde_wormhole::to_vec(&vaa_copy).unwrap(),
merkle_price_updates[0].clone(),
),
&vec![&poster, &price_update_keypair],
None,
)
.await
.unwrap_err()
.unwrap(),
into_transaction_error(ReceiverError::InvalidSignature)
);
let mut vaa_copy: Vaa<&RawMessage> = serde_wormhole::from_slice(&vaa).unwrap();
vaa_copy.signatures[0].signature = vaa_copy.signatures[1].signature;
assert_eq!(
program_simulator
.process_ix_with_default_compute_limit(
PostUpdatesAtomic::populate(
poster.pubkey(),
price_update_keypair.pubkey(),
BRIDGE_ID,
DEFAULT_GUARDIAN_SET_INDEX,
serde_wormhole::to_vec(&vaa_copy).unwrap(),
merkle_price_updates[0].clone(),
),
&vec![&poster, &price_update_keypair],
None,
)
.await
.unwrap_err()
.unwrap(),
into_transaction_error(ReceiverError::InvalidGuardianKeyRecovery)
);
let mut wrong_instruction = PostUpdatesAtomic::populate(
poster.pubkey(),
price_update_keypair.pubkey(),
BRIDGE_ID,
DEFAULT_GUARDIAN_SET_INDEX,
vaa.clone(),
merkle_price_updates[0].clone(),
);
let wrong_guardian_set = get_guardian_set_address(BRIDGE_ID, 1);
wrong_instruction.accounts[1].pubkey = wrong_guardian_set;
assert_eq!(
program_simulator
.process_ix_with_default_compute_limit(
wrong_instruction,
&vec![&poster, &price_update_keypair],
None,
)
.await
.unwrap_err()
.unwrap(),
into_transaction_error(ReceiverError::WrongGuardianSetOwner)
);
}
#[tokio::test]
async fn test_post_updates_atomic_wrong_setup() {
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 price_update_keypair = Keypair::new();
let ProgramTestFixtures {
mut program_simulator,
encoded_vaa_addresses: _,
} = setup_pyth_receiver(vec![], WrongSetupOption::GuardianSetWrongIndex).await;
let poster: Keypair = program_simulator.get_funded_keypair().await.unwrap();
assert_eq!(
program_simulator
.process_ix_with_default_compute_limit(
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_err()
.unwrap(),
into_transaction_error(ReceiverError::InvalidGuardianSetPda)
);
let ProgramTestFixtures {
mut program_simulator,
encoded_vaa_addresses: _,
} = setup_pyth_receiver(vec![], WrongSetupOption::GuardianSetExpired).await;
let poster = program_simulator.get_funded_keypair().await.unwrap();
assert_eq!(
program_simulator
.process_ix_with_default_compute_limit(
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_err()
.unwrap(),
into_transaction_error(ReceiverError::GuardianSetExpired)
);
}