Skip to content

Commit

Permalink
chore(lazer): remove migration code from solana contract (#2257)
Browse files Browse the repository at this point in the history
  • Loading branch information
Riateche authored Jan 15, 2025
1 parent 072bee2 commit 800bb1a
Show file tree
Hide file tree
Showing 4 changed files with 5 additions and 278 deletions.
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.

0 comments on commit 800bb1a

Please sign in to comment.