Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion lazer/contracts/solana/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
"test:anchor": "CARGO_TARGET_DIR=\"$PWD/target\" anchor test",
"test": "pnpm run test:format && pnpm run test:anchor",
"setup": "anchor build && pnpm ts-node scripts/setup.ts",
"migrate_from_0_1_0": "pnpm ts-node scripts/migrate_from_0_1_0.ts",
"check_trusted_signer": "pnpm ts-node scripts/check_trusted_signer.ts"
},
"dependencies": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@ mod signature;

use {
crate::signature::VerifiedMessage,
anchor_lang::{
prelude::*, solana_program::pubkey::PUBKEY_BYTES, system_program, Discriminator,
},
std::{io::Cursor, mem::size_of},
anchor_lang::{prelude::*, solana_program::pubkey::PUBKEY_BYTES, system_program},
std::mem::size_of,
};

pub use {
Expand Down Expand Up @@ -40,24 +38,6 @@ impl TrustedSignerInfo {
const SERIALIZED_LEN: usize = PUBKEY_BYTES + size_of::<i64>();
}

/// TODO: remove this legacy storage type
#[derive(AnchorDeserialize)]
pub struct StorageV010 {
pub top_authority: Pubkey,
pub num_trusted_signers: u8,
pub trusted_signers: [TrustedSignerInfo; MAX_NUM_TRUSTED_SIGNERS],
}

impl StorageV010 {
pub const SERIALIZED_LEN: usize = PUBKEY_BYTES
+ size_of::<u8>()
+ TrustedSignerInfo::SERIALIZED_LEN * MAX_NUM_TRUSTED_SIGNERS;

pub fn initialized_trusted_signers(&self) -> &[TrustedSignerInfo] {
&self.trusted_signers[0..usize::from(self.num_trusted_signers)]
}
}

#[account]
pub struct Storage {
pub top_authority: Pubkey,
Expand Down Expand Up @@ -98,43 +78,6 @@ pub mod pyth_lazer_solana_contract {
Ok(())
}

pub fn migrate_from_0_1_0(ctx: Context<MigrateFrom010>, treasury: Pubkey) -> Result<()> {
let old_data = ctx.accounts.storage.data.borrow();
if old_data[0..ANCHOR_DISCRIMINATOR_BYTES] != Storage::DISCRIMINATOR {
return Err(ProgramError::InvalidAccountData.into());
}
if old_data.len() != StorageV010::SERIALIZED_LEN + ANCHOR_DISCRIMINATOR_BYTES {
return Err(ProgramError::InvalidAccountData.into());
}
let old_storage = StorageV010::deserialize(&mut &old_data[ANCHOR_DISCRIMINATOR_BYTES..])?;
if old_storage.top_authority != ctx.accounts.top_authority.key() {
return Err(ProgramError::MissingRequiredSignature.into());
}
drop(old_data);

let space = ANCHOR_DISCRIMINATOR_BYTES + Storage::SERIALIZED_LEN;
ctx.accounts.storage.realloc(space, false)?;
let min_lamports = Rent::get()?.minimum_balance(space);
if ctx.accounts.storage.lamports() < min_lamports {
return Err(ProgramError::AccountNotRentExempt.into());
}

let mut new_storage = Storage {
top_authority: old_storage.top_authority,
treasury,
single_update_fee_in_lamports: 1,
num_trusted_signers: old_storage.num_trusted_signers,
trusted_signers: Default::default(),
_extra_space: [0; EXTRA_SPACE],
};
new_storage.trusted_signers[..old_storage.trusted_signers.len()]
.copy_from_slice(&old_storage.trusted_signers);
new_storage.try_serialize(&mut Cursor::new(
&mut **ctx.accounts.storage.data.borrow_mut(),
))?;
Ok(())
}

pub fn update(ctx: Context<Update>, trusted_signer: Pubkey, expires_at: i64) -> Result<()> {
let num_trusted_signers: usize = ctx.accounts.storage.num_trusted_signers.into();
if num_trusted_signers > ctx.accounts.storage.trusted_signers.len() {
Expand Down Expand Up @@ -238,19 +181,6 @@ pub struct Initialize<'info> {
pub system_program: Program<'info, System>,
}

#[derive(Accounts)]
pub struct MigrateFrom010<'info> {
pub top_authority: Signer<'info>,
#[account(
mut,
seeds = [STORAGE_SEED],
bump,
)]
/// CHECK: top_authority in storage must match top_authority account.
pub storage: AccountInfo<'info>,
pub system_program: Program<'info, System>,
}

#[derive(Accounts)]
pub struct Update<'info> {
pub top_authority: Signer<'info>,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
use {
anchor_lang::{prelude::AccountMeta, InstructionData},
pyth_lazer_solana_contract::{ed25519_program_args, ANCHOR_DISCRIMINATOR_BYTES},
pyth_lazer_solana_contract::ed25519_program_args,
solana_program_test::{BanksClient, BanksClientError, ProgramTest},
solana_sdk::{
account::Account,
ed25519_program,
hash::Hash,
instruction::{Instruction, InstructionError},
pubkey::{Pubkey, PUBKEY_BYTES},
pubkey::Pubkey,
signature::Keypair,
signer::Signer,
system_instruction, system_program, system_transaction, sysvar,
system_instruction, system_program, sysvar,
transaction::{Transaction, TransactionError},
},
std::env,
Expand Down Expand Up @@ -293,129 +292,3 @@ async fn test_rejects_wrong_offset() {
))
));
}

#[tokio::test]
async fn test_migrate_from_0_1_0() {
let mut program_test = program_test();
// Create a storage PDA account with the data that was produced by the program v0.1.0.
let mut old_storage_data = hex::decode(
"d175ffb9c4af4409aa4dcb5d31150b162b664abd843cb231cee5c0ebf759ce371d9cb36ffc653796\
0174313a6525edf99936aa1477e94c72bc5cc617b21745f5f03296f3154461f214ffffffffffffff7\
f00000000000000000000000000000000000000000000000000000000000000000000000000000000",
)
.unwrap();
let top_authority = Keypair::new();
// Replace top authority pubkey in storage PDA data to allow successful migration.
old_storage_data[ANCHOR_DISCRIMINATOR_BYTES..ANCHOR_DISCRIMINATOR_BYTES + PUBKEY_BYTES]
.copy_from_slice(&top_authority.pubkey().to_bytes());
program_test.add_account(
pyth_lazer_solana_contract::STORAGE_ID,
Account {
lamports: 1733040,
data: old_storage_data,
owner: pyth_lazer_solana_contract::ID,
executable: false,
rent_epoch: 18446744073709551615,
},
);
let mut setup = Setup::with_program_test(program_test).await;
let treasury = setup.create_treasury().await;

// Make sure storage PDA will be rent-exempt after resize.
let tx_transfer = system_transaction::transfer(
&setup.payer,
&pyth_lazer_solana_contract::STORAGE_ID,
10_000_000,
setup.recent_blockhash,
);
setup
.banks_client
.process_transaction(tx_transfer)
.await
.unwrap();

let mut transaction_migrate_contract = Transaction::new_with_payer(
&[Instruction::new_with_bytes(
pyth_lazer_solana_contract::ID,
&pyth_lazer_solana_contract::instruction::MigrateFrom010 { treasury }.data(),
vec![
AccountMeta::new(top_authority.pubkey(), true),
AccountMeta::new(pyth_lazer_solana_contract::STORAGE_ID, false),
AccountMeta::new_readonly(system_program::ID, false),
],
)],
Some(&setup.payer.pubkey()),
);
transaction_migrate_contract.sign(&[&setup.payer, &top_authority], setup.recent_blockhash);
setup
.banks_client
.process_transaction(transaction_migrate_contract)
.await
.unwrap();

let message = hex::decode(
"b9011a82e5cddee2c1bd364c8c57e1c98a6a28d194afcad410ff412226c8b2ae931ff59a57147cb47c7307\
afc2a0a1abec4dd7e835a5b7113cf5aeac13a745c6bed6c60074313a6525edf99936aa1477e94c72bc5cc61\
7b21745f5f03296f3154461f2141c0075d3c7931c9773f30a240600010102000000010000e1f50500000000",
)
.unwrap();

// The contract will recognize the trusted signer without calling `set_trusted`
// because it was present in the original storage PDA data.
setup.verify_message(&message, treasury).await;
}

#[tokio::test]
async fn test_disallows_extra_migrate() {
let mut setup = Setup::new().await;
let treasury = setup.create_treasury().await;

let mut transaction_init_contract = Transaction::new_with_payer(
&[Instruction::new_with_bytes(
pyth_lazer_solana_contract::ID,
&pyth_lazer_solana_contract::instruction::Initialize {
top_authority: setup.payer.pubkey(),
treasury,
}
.data(),
vec![
AccountMeta::new(setup.payer.pubkey(), true),
AccountMeta::new(pyth_lazer_solana_contract::STORAGE_ID, false),
AccountMeta::new_readonly(system_program::ID, false),
],
)],
Some(&setup.payer.pubkey()),
);
transaction_init_contract.sign(&[&setup.payer], setup.recent_blockhash);
setup
.banks_client
.process_transaction(transaction_init_contract)
.await
.unwrap();

let mut transaction_migrate_contract = Transaction::new_with_payer(
&[Instruction::new_with_bytes(
pyth_lazer_solana_contract::ID,
&pyth_lazer_solana_contract::instruction::MigrateFrom010 { treasury }.data(),
vec![
AccountMeta::new(setup.payer.pubkey(), true),
AccountMeta::new(pyth_lazer_solana_contract::STORAGE_ID, false),
AccountMeta::new_readonly(system_program::ID, false),
],
)],
Some(&setup.payer.pubkey()),
);
transaction_migrate_contract.sign(&[&setup.payer], setup.recent_blockhash);
let err = setup
.banks_client
.process_transaction(transaction_migrate_contract)
.await
.unwrap_err();
assert!(matches!(
err,
BanksClientError::TransactionError(TransactionError::InstructionError(
0,
InstructionError::InvalidAccountData
))
));
}
75 changes: 0 additions & 75 deletions lazer/contracts/solana/scripts/migrate_from_0_1_0.ts

This file was deleted.

Loading