Skip to content

Commit 8b187dd

Browse files
authored
feat: make migration safer
1 parent 349462f commit 8b187dd

2 files changed

Lines changed: 26 additions & 18 deletions

File tree

target_chains/solana/programs/core-bridge/src/legacy/processor/close_guardian_set.rs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use crate::{
22
error::CoreBridgeError,
33
legacy::instruction::EmptyArgs,
4-
sdk::legacy::AccountVariant,
5-
state::{GuardianSet, LEGACY_GUARDIANS},
4+
sdk::legacy::{AccountVariant, LegacyAnchorized},
5+
state::{Config, GuardianSet, LEGACY_GUARDIANS},
66
};
77
use anchor_lang::prelude::*;
88

@@ -11,12 +11,19 @@ pub struct CloseGuardianSet<'info> {
1111
#[account(mut)]
1212
recipient: UncheckedAccount<'info>,
1313

14+
#[account(
15+
mut,
16+
seeds = [Config::SEED_PREFIX],
17+
bump,
18+
)]
19+
config: Account<'info, LegacyAnchorized<Config>>,
20+
1421
#[account(
1522
mut,
1623
close = recipient,
1724
seeds = [
1825
GuardianSet::SEED_PREFIX,
19-
guardian_set.inner().index.to_be_bytes().as_ref()
26+
config.guardian_set_index.to_be_bytes().as_ref()
2027
],
2128
bump,
2229
// At least one guardian is from the legacy guardian sets.
@@ -40,6 +47,8 @@ impl<'info> crate::legacy::utils::ProcessLegacyInstruction<'info, EmptyArgs>
4047

4148
/// Processor to remove a guardian set account containing a legacy guardian.
4249
/// This instruction is permissionless - anyone can call it.
43-
fn close_guardian_set(_ctx: Context<CloseGuardianSet>, _args: EmptyArgs) -> Result<()> {
50+
fn close_guardian_set(ctx: Context<CloseGuardianSet>, _args: EmptyArgs) -> Result<()> {
51+
ctx.accounts.config.guardian_set_index =
52+
ctx.accounts.config.guardian_set_index.saturating_sub(1);
4453
Ok(())
4554
}

target_chains/solana/programs/pyth-solana-receiver/tests/test_migrate_guardian_set.rs

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,6 @@ const MAINNET_BRIDGE_FIXTURE: &str = concat!(
6363
"/tests/fixtures/wormhole_core_bridge_solana_mainnet.so"
6464
);
6565

66-
/// Guardian set index mainnet is at today, and therefore the highest index this test creates.
67-
const CURRENT_MAINNET_GUARDIAN_SET_INDEX: u32 = 7;
68-
6966
fn loader_account(state: &UpgradeableLoaderState, elf: Option<&[u8]>) -> Account {
7067
let mut data = bincode::serialize(state).unwrap();
7168
if let Some(elf) = elf {
@@ -186,6 +183,7 @@ fn close_guardian_set_instruction(recipient: Pubkey, guardian_set_index: u32) ->
186183
program_id: BRIDGE_ID,
187184
accounts: vec![
188185
AccountMeta::new(recipient, false),
186+
AccountMeta::new(bridge_address(), false),
189187
AccountMeta::new(
190188
get_guardian_set_address(BRIDGE_ID, guardian_set_index),
191189
false,
@@ -239,8 +237,12 @@ async fn post_encoded_vaa(
239237
encoded_vaa.pubkey()
240238
}
241239

240+
fn bridge_address() -> Pubkey {
241+
Pubkey::find_program_address(&[BridgeConfig::SEED_PREFIX], &BRIDGE_ID).0
242+
}
243+
242244
async fn bridge_config(program_simulator: &mut ProgramSimulator) -> BridgeConfig {
243-
let address = Pubkey::find_program_address(&[BridgeConfig::SEED_PREFIX], &BRIDGE_ID).0;
245+
let address = bridge_address();
244246
let account = program_simulator
245247
.get_account(address)
246248
.await
@@ -361,15 +363,12 @@ async fn test_migrate_guardian_set_from_mainnet_bridge() {
361363
.unwrap();
362364
}
363365

366+
let current_guardian_set_index = bridge_config(&mut program_simulator)
367+
.await
368+
.guardian_set_index;
369+
364370
assert_eq!(
365-
bridge_config(&mut program_simulator)
366-
.await
367-
.guardian_set_index,
368-
CURRENT_MAINNET_GUARDIAN_SET_INDEX,
369-
"the bridge tracks mainnet's current guardian set index"
370-
);
371-
assert_eq!(
372-
guardian_set(&mut program_simulator, CURRENT_MAINNET_GUARDIAN_SET_INDEX)
371+
guardian_set(&mut program_simulator, current_guardian_set_index)
373372
.await
374373
.unwrap()
375374
.keys
@@ -455,7 +454,7 @@ async fn test_migrate_guardian_set_from_mainnet_bridge() {
455454
// in, so nothing below would dispatch to the new code without this.
456455
program_simulator.advance_slot().await.unwrap();
457456

458-
for guardian_set_index in 0..=CURRENT_MAINNET_GUARDIAN_SET_INDEX {
457+
for guardian_set_index in (0..=current_guardian_set_index).rev() {
459458
program_simulator
460459
.process_ix_with_default_compute_limit(
461460
close_guardian_set_instruction(payer.pubkey(), guardian_set_index),
@@ -466,7 +465,7 @@ async fn test_migrate_guardian_set_from_mainnet_bridge() {
466465
.unwrap();
467466
}
468467

469-
for guardian_set_index in 0..=CURRENT_MAINNET_GUARDIAN_SET_INDEX {
468+
for guardian_set_index in 0..=current_guardian_set_index {
470469
assert!(
471470
program_simulator
472471
.get_account(get_guardian_set_address(BRIDGE_ID, guardian_set_index))

0 commit comments

Comments
 (0)